I will return through Monad Transformers: Step by Step as an update, and like many other tutorials it uses Control.Monad.Error, the GHC now gives a warning that this module is out of date, so I switched to Control.Monad.Trans.Eitherfrom the library either: http: //hackage.haskell .org / package / either-3.4 / docs / Control-Monad-Trans-Either.html
Everything is processed smoothly with eval2in the document, since it EitherTis the most external monad. However, after that, everything falls apart - in ReaderTno way is it a value either, and it continues to use everything ErrorTthat I would like to change to EitherT.
Then my idea was to define a class of the type MonadEitherthat was put in the box leftand rightto handle errors, but that was not fruitful. I really don’t understand how type classes in work mtl, and this instance, in particular, should be parameterized by several values, which is confusing. I came up with the following, which compiles after including some syntax extensions:
class (Monad m) => MonadEither l r m | m -> r where
right :: r -> m r
left :: l -> m r
But I can not calculate the instance MonadEither EitherT:
instance Monad m => MonadEither l r (E.EitherT l m) where
right = E.right
left = E.left
Edit: I correctly changed the instance declaration to match E.EitherTand received the following error message:
Illegal instance declaration for ‘MonadEither l r (E.EitherT l m)’
The coverage condition fails in class ‘MonadEither’
for functional dependency: ‘m -> r’
Reason: lhs type ‘E.EitherT l m’ does not determine rhs type ‘r’
In the instance declaration for ‘MonadEither l r (E.EitherT l m)’
, , . , , MonadEither, , .