Problem deriving instances

Simon Peyton-Jones simonpj at microsoft.com
Thu Mar 18 17:09:17 EST 2004


You are playing fast and loose here.

instance (HasBinary ty IO) => HasCodedValue ty

doDecodeIO :: HasCodedValue a => () -> () -> IO a
doDecodeIO codedValue view = 
   let
      act = doDecodeIO1 "foo" codedValue view
   in
      act

doDecodeIO1 :: HasCodedValue a => String -> () -> () -> IO a
doDecodeIO1 desc icsl view = error "foo"


The call to doDecodeIO1 gives rise to a constraint (HasCodedValue t).
GHC is reducing the constraint using the instance declaration, to the
constraint (HasBinary ty IO).  That in turn can be reduced, and ends up
needing HasWrapper.

So in effect you have provided *two* ways for GHC to satisfy the
constraint (HasCodedValue t) -- first, by the instance decl, and second
by the (HasCodedValue a) constraint on doDecodeIO.  This is a Very Bad
Idea.  They overlap with no way to pick one rather than the other.

Why has the behaviour changed?  Because I fixed a bug concerning
functional dependencies a couple of days ago, whose fix requires us to
be a bit more brutal about simplifying constraints for monomorphic
bindings such as that of 'act'.  To see why, look at the comments with
TcSimplify.tcSimplifyRestricted.

In general, instances that look like 
	instance .. => Cls a
are deeply suspicious.  They overlap with absolutely everything.

Simon

| -----Original Message-----
| From: cvs-all-bounces at haskell.org [mailto:cvs-all-bounces at haskell.org]
On Behalf Of George Russell
| Sent: 18 March 2004 14:30
| To: cvs-ghc at haskell.org
| Subject: Problem deriving instances
| 
| With GHC compiled and downloaded from the read-only repository this
morning:
| 
| tar -xzf instances.tar.gz
| cd instances
| make
| 
| produces the error
| 
| CodedValue.hs:14:12:
|      Could not deduce (HasWrapper a IO) from the context
(HasCodedValue a)
|        arising from use of `doDecodeIO1' at CodedValue.hs:14:12-22
|      Probable fix:
|        Add (HasWrapper a IO) to the type signature(s) for `doDecodeIO'
|        Or add an instance declaration for (HasWrapper a IO)
|      In the definition of `act': act = doDecodeIO1 "foo" codedValue
view
|      In the definition of `doDecodeIO':
| 	doDecodeIO codedValue view = let act = doDecodeIO1 "foo"
codedValue view in act
| 
| but for earlier GHCs, for example 6.2, it works.  What is going on?


More information about the Cvs-ghc mailing list