functional dependencies

Simon Peyton-Jones simonpj@microsoft.com
Tue, 23 Jul 2002 17:06:03 +0100


I'm just catching up with some old mail here.

Iavor writes:

| class C a b | a -> b
| class C a b =3D> D a
|=20
| vs.
|=20
| class C a b | a -> b
| class C a b =3D> D a b
|=20
| Hugs accepts both of those, while GHC insists on the second. =20
| The first example is a little shorter and one might argue that if we=20
| know "a" we also know "b", because of the functional depency,=20
| so it is not really a parameter.
|
| On the other hand, i would expect writing "b" in the type=20
| signatures of any of the methods to refer to the particular "b"=20
| determined by the "a", rather than it becomeing universally
| quantified, and perhaps this is more explicit in the second form. =20

Dead right!  Imagine there was a method in class D:

	class C a b =3D> D a where
	   op :: a -> b

The type of 'op' is

	op :: D a =3D> a -> b

You can't really expect that the 'b' here is determined by 'a'!

Still, I suppose that if the methods in class D mention=20
only 'a', then it is strange to require D to be parameterised over
'b'.  Thus, this seems more reasonable:

	class C a b =3D> D a where
	  op :: a -> a

Even this seems odd, because we would get the deduction

	D a |- C a b

(i.e. from a (D a) dictionary you can get a (C a b) dictionary)
and that's only true for a particular 'b'.  My brain is too small
to be sure what I'm talking about here, but I'm strongly inclined
to be conservative here, which GHC is.

Simon