[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.
>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