|
|
|
|
|
by dwohnitmok
1205 days ago
|
|
No the trickier problem is that without dependent types you are forced into a very specific, linear chain of validation or else deal with a combinatorial explosion of functions and types. To take your type as an example, you could imagine a function validation : String -> Maybe FinalWidget
but maybe `validation` is really big and unwieldy and you want to reuse parts of it elsewhere so you break it down into a pipeline of -- Let's say a RawWidget is, operationally, a non-empty string
validation0 : String -> Maybe RawWidget
-- Let's say a RefinedWidget is a string consisting only of capital letters
validation1 : RawWidget -> Maybe RefinedWidget
-- A FinalWidget is a non-empty string of capital letters that has no whitespace
validation2 : RefinedWidget -> Maybe FinalWidget
This is over-constrained. You don't really want to force yourself into a scenario where you must call validation0, then validation1, and finally validation2 because maybe in another code path it's more expedient to do it in another order. But the types don't line up if you do it in another order. And maybe you don't really care about `RawWidget` and `RefinedWidget`, but you're forced to create them just to make sure that you can build up to a `FinalWidget`.This is where dependent types would really help relax those constraints. |
|
Anyway, validation/parsing is mostly pretty simple stuff where the "validate" bit is a simple function... and function composition works just fine.
(Assuming you can name the result type of your parse/validate individually according to your domain.)