I am struggling with the best way to report errors in a set of functions that should compose nicely, in a library I'm working on.
Concretely, I have functions that look like:
foo, bar, baz :: a -> Maybe a
where foo
can fail in only one way (a good fit for Maybe
), but bar
and baz
can fail in two different ways each (good fits for Either BarErrors
and Either BazErrors
).
One solution is to create:
data AllTheErrors = TheFooError
| BarOutOfBeer
| BarBurnedDown
| ...
and make all the functions return Either AllTheErrors
, which expresses the range of errors that might be raised by a composed sequence of these functions at the expense of expressing the range of errors possible for each individual function.
Is there a way I can get both? Maybe with something other than monadic composition? Or with type families (waves hands)...?