I have a type level numbers
data Z deriving Typeable
data S n deriving Typeable
and n-ary functions (code from fixed-vector package)
-- | Type family for n-ary functions.
type family Fn n a b
type instance Fn Z a b = b
type instance Fn (S n) a b = a -> Fn n a b
-- | Newtype wrapper which is used to make 'Fn' injective. It's also a
-- reader monad.
newtype Fun n a b = Fun { unFun :: Fn n a b }
I need function like
uncurryN :: Fun (n + k) a b -> Fun n a (Fun k a b)
I read several articles about type level computations, but all about type safe list concatenation.
You can do this without any type classes by constructing a datatype which can represent the type
Nat
on the data level:If you don't like explicitly mentioning the
n
parameter, thats ok since you can always go back and forth between a function which takes an parameter as a type class and which takes a parameter as data:This required a bit of care in unwrapping/rewrapping the
Fun
newtype. I also exploited theDataKinds
extension.