id summary reporter owner description type status priority milestone component version resolution keywords cc os architecture failure testcase blockedby blocking related differential
1549 ghc derives different type signature for equal functions with overlapping instances int-e "Insert ""This flag does not change ghc's behaviour when no verlapping instances are present."" after ""The -fallow-overlapping-instances lag instructs GHC to allow more than one instance to match, provided here is a most specific one."" in http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#instance-overlap
(old description follows for reference)
The code below derives two different type signatures for the same function in two different modules.
One of these modules defines a new instance for the `Monad` class. What's interesting is that this causes the type checker to derive a more general type than before. I think that's a bug.
Another interesting point is that the code below works without -fallow-overlapping-instances,
but if the instances from `A.hs` and from `B.hs` are combined in a single file, the compiler complains very loudly. The derived types are unaffected by `-fallow-overlapping-instances`.
{{{
==> A.hs <==
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
module A (MaybeT (..), module Control.Monad) where
import Control.Monad
newtype MaybeT m a = MaybeT {runMaybeT :: m (Maybe a)}
instance Monad m => Monad (MaybeT m)
==> B.hs <==
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
module B (qqq) where
import A
data Foo a = Foo
instance Monad (MaybeT Foo) where
qqq _ = runMaybeT (runMaybeT (return 1) >> return 2)
==> C.hs <==
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
module C (rrr) where
import A
rrr _ = runMaybeT (runMaybeT (return 1) >> return 2)
==> D.hs <==
module D (qqq, rrr) where
import B
import C
{-
# ghci -fallow-overlapping-instances D.hs
GHCi, version 6.7.20070716: http://www.haskell.org/ghc/ :? for help
(...)
Ok, modules loaded: C, D, A, B.
*D> :t qqq
qqq :: (Monad (A.MaybeT m), Num t1) => t -> m (Maybe t1)
*D> :t rrr
rrr :: (Monad m, Num t1) => t -> m (Maybe t1)
*D> :i MaybeT
newtype MaybeT m a = MaybeT {runMaybeT :: m (Maybe a)}
-- Defined at A.hs:6:8-13
instance [overlap ok] (Monad m) => Monad (MaybeT m)
-- Defined at A.hs:8:0-35
-}
}}}
I think that the type derived for `qqq` is correct in the presence of overlapping instances." bug closed low Documentation 6.7 fixed Linux x86