#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 Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs