[Haskell] generic currying (type classes and functional
dependencies)
Esa Pulkkinen
esa.pulkkinen at kotiposti.net
Wed May 12 00:03:54 EDT 2004
In message <1084241553.27784.25.camel at localhost>, Duncan Coutts writes:
>I'm trying to write a generic curry (& uncurry) function that works for
>functions of any arity. I have a couple solutions that nearly work, both
>involving type classes.
[SNIP]
>Any insight or suggestions would be interesting.
Here's one solution, which I think is more general than what you ask,
but I guess it should work as well. It's based on adjunctions from
category theory:
class (Functor path, Functor space) =>
Adjunction path space | path -> space, space -> path where
leftAdjunct :: (path top -> bot) -> top -> space bot
unit :: top -> space (path top)
rightAdjunct :: (top -> space bot) -> path top -> bot
counit :: path (space bot) -> bot
-- minimum required impl: unit xor leftAdjunct
-- minimum required impl: counit xor rightAdjunct
unit = leftAdjunct id
leftAdjunct f = fmap f . unit
counit = rightAdjunct id
rightAdjunct g = counit . fmap g
-- Here are some instances for different arities:
instance Adjunction ((,) a) ((->) a) where
unit t = \arg -> (arg,t)
counit (x,f) = f x
newtype Func2 a b c = Func2 (a -> b -> c)
-- Func2 is only needed due to syntax of partial type constructor application
instance Adjunction ((,,) a b) (Func2 a b) where
unit t = Func2 (\arg1 arg2 -> (arg1,arg2,t))
counit (arg1,arg2,Func2 f) = f arg1 arg2
instance Functor ((,,) a b) where
fmap f (x,y,z) = (x,y,f z)
instance Functor (Func2 a b) where
fmap f (Func2 g) = Func2 (\a b -> f (g a b))
Here, 'leftAdjunct' is a generalization of curry and rightAdjunct is a
generalization of uncurry.
--
Esa Pulkkinen
More information about the Haskell
mailing list