What are the difference in usage between Either and Except in Haskell?
The difference is in the instance of Alternative
. The "base" package does not export any for Either
, as I understand because the authors didn't want to introduce a bias towards any of the values, which on itself is because Either
is supposed to be a general sum-type, and representing the possibility of errors is only a special case. However the "transformers" package does provide an orphan instance, which binds it to the Error
class:
Error e => Alternative (Either e)
However the community has never accepted either the typeclass or the orphan instance, which is why it is now deprecated. IOW you can look at it as if Either
still has no instance of Alternative
.
The Except
type does have a non-orphan instance, which doesn't even bind the user to any made-up classes, but Monoid
instead:
(Monad m, Monoid e) => Alternative (ExceptT e m)
It is also worth noting, that for cases when dealing with validation and accumulating all errors, the Validation
abstraction is more appropriate. There is a tradeoff though: it cannot be a monad, but it is a selective (between applicative and monad) and an alternative.
As noted in the comments, it's easy to convert between Except
& Either
. The runtime representation is the same, even.
I would always choose to use Either
. It's ubiquitous in libraries. I very rarely see Except
.
Except
is a special case of ExceptT, which you will see in libraries. If you find yourself writing a lot of functions with Reader SomeType (Either e a)
or IO (Either e a)
or Monad m => m (Either e a)
, then you might want to consider ExceptT
. It's fine not to worry about it until then - Either
is easier to use until it isn't.