broken Monad Either instance?
Christian Maeder
Christian.Maeder at dfki.de
Wed Nov 30 10:32:02 CET 2011
I would rather not change my (nice) monadic typeCheck function.
Do we have a "standard" monad instance to recover the "error-free"
version from the monad version (that is more informative than Maybe)?
Cheers Christian
Am 29.11.2011 14:47, schrieb Ben Millwood:
> On Tue, Nov 29, 2011 at 11:36 AM, Christian Maeder
> <Christian.Maeder at dfki.de> wrote:
>>
>> Previously correct programs can now crash quite unpredictably without
>> warnings!
>>
>
> Yeah, this bit the HTTP library too, but there was no way to address
> the infelicity without this happening.
>
>> My use case is (or better was) monadic code like:
>>
>> typeCheck :: Monad m => ... -> m (...)
>>
>> where I used the "Either String" Monad instance to extract the fail
>> messages:
>>
>> case typeCheck ... of
>> Right ... -> ...
>> Left ... -> ....
>>
>> For this I now need another monad! Which one is recommended?
>>
>> Cheers Christian
>
> typeCheck :: ... -> Either String ...
>
> or even better, define a real error type, TypeError, and give
> typeCheck the return type Either TypeError ... which makes matching
> cases and reacting to problems much more straightforward, as well as
> up-front showing you the ways it can fail.
>
> You can then convert back to the generic version with 'either fail
> return' (or 'either (fail . show) return' in the TypeError case) but
> you probably won't need to most of the time, you'll just use the
> function as-is. Inside typeCheck, you just use Left instead of fail.
> If you use the do pattern-match failure, you isolate it in little
> Maybe blocks like the one I have above, with your own error message
> for each one. Something like:
>
> typeCheck :: AST -> Either TypeError Type
> typeCheck (Tuple xs) = do
> -- check the tuple has>= 2 elements
> check SyntaxError $ do
> [_,_]<- return (take 2 xs)
> return ()
> -- type check them
> TupleType<$> mapM typeCheck xs
>
> check :: TypeError -> Maybe a -> Either TypeError a
> check err = maybe (Left err) Right
>
> Admittedly the 'return ()' is a little ugly, but the fact you're
> explicit about the error you're throwing makes up for it in my
> opinion. Notice that the line using mapM typeCheck xs wouldn't work in
> the past unless TypeError was an instance of Error; often there isn't
> a sensible way for it to be so.
More information about the Libraries
mailing list