a little more experimentation leaves me confused. consider

[4]
  class C a b c | a -> b -- , a -> c
  instance C a b b => C [a] [b] [b]

  Hugs:
  :t undefined :: C [x] y z => (x,y,z)
  undefined :: C [a] [b] c => (a,[b],c)

  GHCi:
  :t undefined :: C [x] y z => (x,y,z)
  undefined :: C [x] y z => (x,y,z) :: (C [x] [b] z) => (x, [b], z)

both systems improve 'y' to '[b]', but not to '[b] where z=[b]'.

ok, the third parameter is not in range of an FD, so cannot be
instantiated by improvement, and without that, 'y' cannot be
instantiated as far as the FD would suggest. it is slightly
surprising that 'y' get partially instantiated at this stage.

My understanding of an FD a -> b is to improve, or in other words instantiate, b as much as possible based on information from a.

With C [x] y z we know for sure that y must be [b] for some b. Improvement adds (propagates) this information we know for sure. With our limited information, we may not know what b is, but just knowing the list type constructor [] may already be useful. For instance, if we had a second type class constraint D y for which there is an instance

        instance D [a] where ...

Then inferring that y = [b] will allow us to figure out that we can use the above instance for it.

however, if we try to help the process along by instantiating
'z' to '[b]' ourselves, we get:

[5]
  Hugs:
  :t undefined :: C [x] y [b] => (x,y,[b])
  undefined :: C [a] [b] [c] => (a,[b],[c])

  GHCi:
  :t undefined :: C [x] y [b] => (x,y,[b])
undefined :: C [x] y [b] => (x,y,[b]) :: (C [x] [b1] [b]) => (x, [b1], [b])

i would have expected 'C a c c => (a,[c],[c])' here, as
only instantiation of 'y' is required; so my intuition is still off,
and neither [A] nor [B] seems to capture Hugs' interpretation.

You did not provide the FD a -> c (or even a -> b c). That means that you did not allow the type checker to improve c based on a. Nor did you provide the FD a c -> b. For that reason the type checker does not use any information from the third parameter to improve the second parameter.

It does indeed feel somewhat strange, because there is no alternative for y (except if you allow overlapping instances and add e.g. an instance C [a] [b] [Int]).

Cheers,

Tom

--
Tom Schrijvers

Department of Computer Science
K.U. Leuven
Celestijnenlaan 200A
B-3001 Heverlee
Belgium

tel: +32 16 327544
e-mail: [EMAIL PROTECTED]
url: http://www.cs.kuleuven.be/~toms/
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to