broken Monad Either instance?

Erik Hesselink hesselink at gmail.com
Wed Nov 30 11:39:26 CET 2011


ErrorT from mtl still has a 'fail' implementation that returns a Left.

Erik

On Wed, Nov 30, 2011 at 10:32, Christian Maeder
<Christian.Maeder at dfki.de> wrote:
> 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.
>
>
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://www.haskell.org/mailman/listinfo/libraries



More information about the Libraries mailing list