In message <1084241553.27784.25.camel@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