Search code examples
haskellcompilationcabalghci

ghci won't interpret file but cabal build succeeds?


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))

Solution

  • 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.