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