Functional dependencies question
Tue, 13 May 2003 08:58:35 +0100
Think of it like this. Should this be acceptable?
f :: a -> a -> a
f x y =3D x && y
No, because the type (forall a. a->a->a) is plainly more general than
the actual function. The type tempts you to think that you could write
f 3 4
but you can't. But I suppose you could argue that the function
definition should be allowed, but if you ever called (f 3 4) you should
get an error "Int found where Bool expected".
Your signature is
bar :: (Foo Char t) =3D> t
and we know (from the instance decl) that t must be Bool. Any other
call to bar would be illegal, just as any cal to 'f' above is illegal,
except at type Bool.
In general, it seems to make sense to reject definitions as early as
possible, hence GHC and Hugs reject it.
It is undoubtedly odd that adding an instance declaration makes a legal
program illegal, and that might be a reason for relaxing the rule... but
it's not entirely easy to implement such a relaxation.
| -----Original Message-----
| From: firstname.lastname@example.org
[mailto:email@example.com] On Behalf Of Andrew
| J Bromage
| Sent: 12 May 2003 06:10
| To: firstname.lastname@example.org
| Subject: Functional dependencies question
| G'day everyone.
| Suppose I have code like this:
| class Foo a b | a -> b where
| foo :: a -> b
| bar :: (Foo Char t) =3D> t
| bar =3D foo 'a'
| All well and good so far. Let's add an instance of Foo...
| instance Foo Char Bool where
| foo c =3D isAlpha c
| Now neither GHC nor Hugs will allow this to compile, as the declared
| type of bar is "too general".
| This seems intuitively the wrong behaviour. Either the original
| program was incorrect (as there was no visible instance of Foo for
| type Char) or the amended program is correct (since the type of bar
| is no more general than it was in the first version).
| Andrew Bromage
| Haskell-Cafe mailing list