#7437: peculiar behaviour with default instances and type variables
----------------------------------------+-----------------------------------
Reporter: bos | Owner:
Type: bug | Status: new
Priority: normal | Component: Compiler
Version: 7.6.1 | Keywords:
Os: Unknown/Multiple | Architecture: Unknown/Multiple
Failure: GHC accepts invalid program | Blockedby:
Blocking: | Related:
----------------------------------------+-----------------------------------
Here is a small module that has perplexing behaviour under GHC 7.6.1.
In its current form, it compiles and behaves correctly.
There are two lines commented out in the module.
Uncomment the first type signature for "default put", comment out the
second one, and recompile. You'll get an "ambiguous constraint" error.
Now uncomment the {{{FlexibleInstances}}} pragma. The error changes to "no
instance for (Put a0)", and moves to the bottom of the file.
I encountered this problem earlier today, in a module (in the binary
package) that had {{{FlexibleInstances}}} and a default signature where
the name of the type variable did not match the name of the class's type
variable.
In that module, I did not have an instance like the one at the bottom of
the file, so the module compiled cleanly and without error.
It was not until I tried to compile the module that depended on it that
the error occurred. It took me three hours of poking around at random
before I accidentally figured out what was wrong.
It would be very helpful if GHC either accepted default signatures with
non-matching type variables (which seems correct to me) or rejected them,
but did one or the other consistently. Finding a mysterious type error in
a downstream module because of a very hard-to-spot error in an upstream
module turned out to be extremely difficult.
{{{
{-# LANGUAGE DefaultSignatures, FlexibleContexts, DeriveGeneric #-}
-- {-# LANGUAGE FlexibleInstances #-}
module Whee where
import GHC.Generics
class GPut f where
gput :: f a -> [()]
class Put a where
put :: a -> [()]
-- default put :: (Generic t, GPut (Rep t)) => t -> [()]
default put :: (Generic a, GPut (Rep a)) => a -> [()]
put = gput . from
instance GPut U1 where
gput U1 = []
instance GPut a => GPut (M1 i c a) where
gput = gput . unM1
data Foo = Foo
deriving (Generic)
instance Put Foo
}}}
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7437>
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