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