I have a simple definition for a Nat and a definition for types indexed by Nat's, Natty.
data Nat :: * where
Zero :: Nat
Suc :: Nat -> Nat
data Natty :: Nat -> * where
Zy :: Natty Zero
Sy :: Natty n -> Natty (Suc n)
My goal is to create a function that, given a type indexed by Nat n and a type indexed by Nat m, will produce a type indexed by type Nat n + m.
For example, foo (Sy Zy) (Sy $ Sy Zy) = Sy $ Sy $ Sy Zy
Nat addition is simple and is defined as such:
nAdd :: Nat -> Nat -> Nat
nAdd x Zero = x
nAdd x (Suc y) = Suc $ nAdd x y
I had thought that foo would be defined similarly in the following way:
foo :: Natty n -> Natty m -> Natty (nAdd n m)
foo x Zy = x
foo x (Sy y) = Sy $ foo x y
But this leads to an interesting error:
Could not deduce: n ~ nAdd n 'Zero
from the context: m ~ 'Zero
Why can't haskell deduce that n ~ nAdd n 'Zero? Is there a simple way to fix this or will a different approach be needed?
Thanks, any input would be greatly appreciated. The following extensions are also used.
{-# LANGUAGE DataKinds, KindSignatures, GADTs #-}
nAdd
in a type signature.Natty (nAdd n m)
just treatsnAdd
as a unique, curiously-named type variable. Perhaps you want to use a closed type family instead? Alternatively, thesingletons
library can promote the function to a type family for you. – Alexis King