When I load a certain file in ghci
/ cabal repl
, I get the following error message:
No instance for (Control.Monad.Trans.Class.MonadTrans
(EitherT Error))
arising from a use of ‘lift’
However, EitherT a
is definitely an instance of MonadTrans
; it's part of the package. cabal build
succeeds; too. It seems ghci
and cabal repl
don't know about EitherT
typeclass instances (liftIO
produces a similar error) for some reason (but cabal build
is happy with it)?
Has anyone encountered anything like this before?
Thanks in advance! :)
EDIT:
Yup; most of the instances are missing:
λ :i EitherT
type role EitherT nominal representational nominal
newtype EitherT e (m :: * -> *) a
= EitherT {runEitherT :: m (Either e a)}
-- Defined in ‘Control.Monad.Trans.Either’
instance Eq (m (Either e a)) => Eq (EitherT e m a)
-- Defined in ‘Control.Monad.Trans.Either’
instance Monad m => Monad (EitherT e m)
-- Defined in ‘Control.Monad.Trans.Either’
instance Monad m => Functor (EitherT e m)
-- Defined in ‘Control.Monad.Trans.Either’
instance Ord (m (Either e a)) => Ord (EitherT e m a)
-- Defined in ‘Control.Monad.Trans.Either’
instance Read (m (Either e a)) => Read (EitherT e m a)
-- Defined in ‘Control.Monad.Trans.Either’
instance Show (m (Either e a)) => Show (EitherT e m a)
-- Defined in ‘Control.Monad.Trans.Either’
λ
However, if I run cabal get either
to get the source code for the package, and open that in cabal repl
, it does have all the instances. So... uh... why doesn't it know about those instances when I import the package instead of loading the source code?
EDIT5:
Ok, this is seriously weird. Running ghci
(not cabal repl
inside the either-4.3.3.2
source directory and then running :l src/Control/Monad/Trans/Either.hs
produces missing typeclass instance errors for EitherT
, namely MonadTrans
λ :l src/Control/Monad/Trans/Either.hs
[1 of 1] Compiling Control.Monad.Trans.Either ( src/Control/Monad/Trans/Either.hs, interpreted )
src/Control/Monad/Trans/Either.hs:287:14:
Could not deduce (transformers-0.3.0.0:Control.Monad.Trans.Class.MonadTrans
(EitherT e))
My guess, which wouldn't be visible from just the code, is that you have two versions of transformers
installed: A newer one that is loaded directly by GHCi and an older one that is used by the installed either
package. Or possibly even more packages are involved through indirect dependencies.
Then MonadTrans
from one gets mixed with EitherT
from the other, which knows nothing about it.
cabal
, on the other hand, makes sure to use one consistent version.
To check if there are two versions installed, use
ghc-pkg list transformers
You can give GHCi a -package
flag (or use :set
) to force a version to be used, although that will only affect loaded files, not installed packages.
Also, everyone seems to be recommending cabal
sandboxes these days to avoid such problems.