Reputation:
Is it possible to accumulate error messages in the ErrorT monad? I would like to accumulate more that one error.
Upvotes: 2
Views: 651
Reputation: 27776
You can use the Errors
Applicative from Control.Applicative.Lift
from transformers:
ghci> import Control.Applicative
ghci> import Control.Applicative.Lift
ghci> failure ['a'] *> pure () <* failure ['b']
Other (Constant "ab")
It returns the list of errors, if there are any, or the successful result.
This type is usually known as the "Validation" Applicative. There are other implementations of it available on Hackage. One posible improvement is to relax the requirement for the failure container to be a Monoid
, allowing Semigroup
s as well.
Notice that the Errors
type is not a Monad
. But you can combine it with other Applicative
s using Data.Functor.Compose
.
The MonadPlus
instance for ExceptT
has a related but not identical behaviour: it returns the first success, if there is any, or a list of errors:
ghci> throwE ['a'] `mplus` return () `mplus` throwE ['b'] :: ExceptT [Char] Identity ()
ExceptT (Identity (Right ()))
ghci> throwE ['a'] `mplus` throwE ['b'] :: ExceptT [Char] Identity ()
ExceptT (Identity (Left "ab"))
Upvotes: 9