broken Monad Either instance?
haskell at benmachine.co.uk
Tue Nov 29 14:47:00 CET 2011
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
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
> 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)
-- 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