[Haskell] generic currying (type classes and functional
dependencies)
Malcolm Wallace
Malcolm.Wallace at cs.york.ac.uk
Tue May 11 17:57:14 EDT 2004
Duncan Coutts <duncan.coutts at worcester.oxford.ac.uk> writes:
> So I thought that functional dependencies might help because the curried
> type should uniquely determine the uncurried type (and vice versa).
> However if I change the class declaration to:
>
> class Curry tupled curried | tupled -> curried, curried -> tupled where
> genericCurry :: tupled -> curried
> genericUncurry :: curried -> tupled
>
> Then the compiler complains about my instance declarations:
>
> Functional dependencies conflict between instance declarations:
> ./Curry.hs:11:0: instance Curry ((a, b) -> c) (a -> b -> c)
> ./Curry.hs:16:0:
> instance (Curry ((b, c) -> d) (b -> c -> d)) =>
> Curry ((a, (b, c)) -> d) (a -> b -> c -> d)
>
> I don't fully understand why this is the case, but it is to do with the
> nested pairing, because individual instance declarations for 3-tuples,
> 4-tuples work fine.
With a little alpha-renaming:
instance Curry ((a, b) -> c) (a -> b -> c)
instance (Curry ((e, f) -> g) (e -> f -> g)) =>
Curry ((d, (e, f)) -> g) (d -> e -> f -> g)
It should be fairly easy to see that the type
(d, (e, f)) -> g
is an instance of
(a, b) -> c
where a==d and b==(e,f) and c==g. Also
(d -> e -> f -> g)
is an instance of
(a -> b -> c)
where a=d and b==e and c==(f->g). So for one thing your two instances
overlap, but additionally, the type-variables do not unify, because
in the tupled part of the Curry predicate, b==(e,f), but in the curried
part of the predicate, b==e.
Regards,
Malcolm
More information about the Haskell
mailing list