Data.Typeable and default instances

Simon Peyton-Jones simonpj at
Mon Dec 5 05:07:44 EST 2005


You've found a strange corner case.   Here's a cut-down example, which
fails in exactly the same way.

	class Baz v x where
	   foo :: x -> x	-- Notice that v is not mentioned
	   foo y = y

	instance Baz Int Int

But it succeeds if you put the instance explicitly:

	instance Baz Int Int where foo y = y

GHC does not actually macro-expand the instance decl.  Instead, it
defines a default method function, thus

	$dmfoo :: Baz v x => x -> x
	$dmfoo y = y

Notice that this is an ambiguous type: you can't call $dmfoo without
triggering an error.  And when you write an instance decl, it calls the
default method:

	instance Baz Int Int where foo = $dmfoo

I'd never thought of that.  You might think that we should just *infer*
the type of the default method (here forall a. a->a), but in the
presence of higher rank types etc we can't necessarily do that.

So I'm not sure what to do.  I've added it as an expected-failure test
(tc199).  I have not added a SourceForge bug because the original
program seems so implausible.  

Meanwhile, the workaround is to define your own default method, thus:
	dmfoo :: x -> x
	dmfoo y = y

	instance Baz Int Int where foo = dmfoo


| -----Original Message-----
| From: glasgow-haskell-users-bounces at
| bounces at] On Behalf Of Jim Apple
| Sent: 04 December 2005 17:24
| To: glasgow-haskell-users at
| Subject: Data.Typeable and default instances
|  > {-# OPTIONS -fglasgow-exts #-}
|  >
|  > import Maybe
|  > import Data.Typeable
|  >
|  > data Nil = Nil deriving (Eq,Typeable,Show)
|  >
|  > class (Typeable t) => List a t where
|  >     init :: (t -> b) -> (forall y . (List a y) => y -> b)
|  >     init f z = fromJust $ do x <- cast z
|  >                              return $ f x
|  >
|  > instance List a Nil where
|      Could not deduce (List a1 y)
|        from the context (List a Nil, Typeable Nil, List a y)
|        arising from use of `Main.$dminit' at Main.hs:21:0
|      Probable fix: add (List a1 y) to the class or instance method
| `Main.init'
|      In the definition of `init': init = Main.$dminit
|      In the definition for method `Main.init'
|      In the instance declaration for `List a Nil'
| but copying and pasting the code from init to the instance declaration
| works fine.
| Jim
| _______________________________________________
| Glasgow-haskell-users mailing list
| Glasgow-haskell-users at

More information about the Glasgow-haskell-users mailing list