id,summary,reporter,owner,description,type,status,priority,milestone,component,version,resolution,keywords,cc,os,architecture,failure,testcase,blockedby,blocking,related,differential,wikipage
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,,,,,,,