[Haskell-beginners] MonadError
Nick Vanderweit
nick.vanderweit at gmail.com
Sat Aug 25 17:05:19 CEST 2012
The use of throwError :: e -> m a on a String type implies that e is String,
but you have declared that e is more general. Here is a version that type
checks:
x :: (Error e, MonadError e m) => Float -> m Float
x y = if y == 0
then throwError . strMsg $ "zero"
else return y
strMsg is part of the Error class, and will allow you to represent these
errors more generally.
Nick
On Saturday, August 25, 2012 12:30:23 AM Dennis Raddle wrote:
> I'm enjoying writing code that uses the Error monad to provide errors,
> which I can catch and rethrow to add context. Kind of like getting a stack
> trace with any context I want every time an error happens.
>
> In most cases I use monad transformers, so the actual monad type would be
> something like "ErrorT String (State Int) a"
>
> But much of my code that handles errors doesn't need to know the entire
> context. It uses throwError, but otherwise doesn't care anything else about
> the type of the monadic computation. I.e., it needs to "know" that it's
> inside a monadic computation of a typeclass MonadError.
>
> So I discovered that I could declare a function like this:
>
> x :: MonadError String m => Float -> m Float
> x y = if y == 0
> then throwError "zero"
> else return y
>
> My awareness of class constraints is vague, so as I worked on this problem
> I knew in a fuzzy way it was going to look something like that, but I had
> to experiment.
>
> Also, because I put "String" in the class constraint, I need to turn on
> FlexibleContexts.
>
> So my question is, how would I do it without making "String" explicit?
>
> If I put
>
> x:: MonadError e m => Float -> m Float
> x y = if y == 0
> then throwError "zero"
> else return y
>
> I get errors saying "couldn't match expected type e against inferred type
> [Char]" and something about functional dependencies
>
> I fiddled with it a bit but couldn't make it work.
More information about the Beginners
mailing list