#1549: ghc derives different type signature for equal functions with overlapping
instances
------------------------------+---------------------------------------------
    Reporter:  int-e          |        Owner:          
        Type:  proposal       |       Status:  reopened
    Priority:  low            |    Milestone:          
   Component:  Documentation  |      Version:  6.7     
    Severity:  trivial        |   Resolution:          
    Keywords:                 |   Difficulty:  Unknown 
          Os:  Linux          |     Testcase:          
Architecture:  x86            |  
------------------------------+---------------------------------------------
Changes (by int-e):

  * resolution:  invalid =>
  * component:  Compiler (Type checker) => Documentation
  * severity:  normal => trivial
  * priority:  normal => low
  * status:  closed => reopened
  * type:  bug => proposal

Old description:

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

New description:

 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.

Comment:

 Thank you.

 The connection that I hadn't made is that type inference (in particular,
 choosing an instance to use for type classes for a monotype) and
 constraint simplification (which affects polymorphic types) are really the
 same thing.

 Once that misconception is resolved the behaviour is just as expected. The
 documentation could be clearer about the fact that allowing overlapping
 instances does not change the behaviour for the case when none are present
 though.

 Maybe inserting "This flag does not change ghc's behaviour when no
 overlapping instances are present." after "The -fallow-overlapping-
 instances flag instructs GHC to allow more than one instance to match,
 provided there is a most specific one." would clear that up?

 Bertram

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1549>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to