Yet more on functional dependencies

Simon Peyton-Jones
Fri, 26 Jan 2001 02:42:33 -0800

| | I am finding functional dependencies confusing.  (I suspect I am=20
| | not alone.)  Should the following code work?
| |=20
| | class HasConverter a b | a -> b where
| |    convert :: a -> b
| |=20
| | instance (HasConverter a b,Show b) =3D> Show a where
| |    show value =3D show (convert value)
| It's a separate issue.  There's no reason why a system using
| functional dependencies *should* support this.  But it is an
| attractive and useful extension that such a system would
| probably *want* to include.  (i.e., it's a desirable feature,
| not a requirement.)

There are two things going on here

a) The 'head' of the instance declaration is just "Show a", so this
purports to give an instance declaration for all types "a".  So it
overlaps with other instance declarations, and GHC currently rejects
it for that reason.  (Arguably, if you accept overlapping instance=20
declarations, then this should be acceptable too.)

b) There's a "b" in the instance declaration context that doesn't
appear in the head.  This is quite OK, because the functional dependency
ensures that "a" uniquely determines "b". =20

So here's a variant that works in the (as-yet-unreleased) GHC 5.0:

	data Foo a =3D MkFoo a

	instance (HasConverter a b,Show b) =3D> Show (Foo a) where
   		show (MkFoo value) =3D show (convert value)

[Incidentally, functional dependencies don't work at all in GHC 4.08;
even try.]