I have the following monad transformer for dealing with errors in Haskell.
instance (Monad m, Error e) => Monad (EitherT e m) where
return = EitherT . return . return
m >>= k = EitherT $ do
a <- runEitherT m
case a of
Left l -> return (Left l)
Right r -> runEitherT (k r)
fail = EitherT . return . Left . strMsg
It works fairly well, as I can instantiate Error with a custom class and have a pretty flexible means by which to handle errors.
fail is a bit silly, though, because it is type String -> EitherT e m, and the String restriction can be an annoying way to create errors. I end up with a whole lot of:
instance Error BazError where
strMsg "foo" = FooError -- oh look we have no error context
strMsg "bar" = BarError -- isn't that nice
What I’d like to do is create a new function, like fail, that is of type a -> e so that I can remove the (Error e) restriction. fail is especially convenient when the monad stack gets large, like when I end up with
EitherT BazError (StateT [BazWarning] IO) Foo
Is there a way to create a function that has the same behavior as fail with a less restrictive type? Or is fail implemented using deep haskell dark magic?
Well,
failis called if you have a pattern-match failure in a do block, like if you haveJust x <- somethingandsomething‘s result isNothing. Apart from that,failis an ordinary function.For the problem with
strMsg "foo" = FooErroretc, doesthrowErroroffer a nicer interface for your use case?