The Japanese version is at はてなブログ.
fail was removed from
Monad a long time ago, I prefer to type computations that may fail to
foo :: MonadFail m => m a
This allows you to instantiate
IO within the
IO context, and to instantiate it to
Maybe within the pure context for example.
-- within IO context foo :: IO a -- within pure context foo :: Maybe a
It is not happy that
Maybe discards the failure messages. So should we use
Either is not actually a
MonadFail instance. There was a proposal about this which was rejected because of the following reason.
the instances "get in the way of a user who wants to treat the parameter uniformly"
That being so I wanted the following
Result type as the simplest
newtype Result a = Result (Either String a) instance MonadFail Result where fail = Left
There is actually an equivalent of this but it is deprecated. It is
ErrorT of the mtl package.
I released the either-result package which contains
Result and some functions.
Result is an alias of
ResultT Identity and
ResultT is a newtype of
ExceptT of the transformers package.
type Result a = ResultT Identity a newtype ResultT m a = ResultT (ExceptT String m a)
What is the difference between
ExceptT is about
MonadFail instances. On
fail wraps a message with
Left, while on
ExceptT it calls
fail of its base monad. Because of it, on
ResultT its base monad is requested to be just
Monad, but on
ExceptT its one is requested to be
instance Monad m => MonadFail (ResultT m) where … instance MonadFail m => MonadFail (ExceptT e m) where …
You can use
ResultT is also
MonadError instance of the mtl package.
MonadThrow type class, isn't it? Yes, the exceptions package has
MonadCatch type classes. These requests something thrown and caught to be
Exception instances. In my opinion, if you want to recognise thrown and caught things by their type, you should use them. And if you want just messages, use
class Monad m => MonadThrow m where throwM :: Exception e => e -> m a class MonadThrow m => MonadCatch m where catch :: Exception e => m a -> (e -> m a) -> m a class Monad m => MonadFail m where fail :: String -> m a
- on defining, type computations which may fail to
MonadFail m => m a
- on using, use it as
IOcontext for example
- on using, use it as
Result awithin a pure context
- add star to the GitHub repository 😉