{-# LANGUAGEEmptyDataDecls,
Rank2Types,
TypeFamilies,
TypeOperators,
ScopedTypeVariables,
UndecidableInstances #-}
moduleTypeNat (Z, S,
(:+:), (:*:), (:^:),
TypeNat, reflectTypeNat,
Zero, Succ, One, Two, Three, Four) whereinfixl 6 :+:
infixl 7 :*:
infixr 8 :^:
dataZdataS a
type family a :+: b
typeinstanceZ :+: a = a
typeinstanceS a :+: b =S (a :+: b)
type family a :*: b
typeinstanceZ :*: a =ZtypeinstanceS a :*: b = a :*: b :+: b
type family a :^: b
typeinstance a :^: Z=SZtypeinstance a :^: S b = a :^: b :*: a
classTypeNat a wherereflectTypeNat:: (Numb) =>a->binstanceTypeNatZwhere
reflectTypeNat _ = 0
instance (TypeNat a) => TypeNat (S a) where
reflectTypeNat _ = reflectTypeNat (undefined :: a) + 1
reifyTypeNat:: (Numa, Orda) =>a-> (forallb . (TypeNatb) =>b->c) ->creifyTypeNat 0 k = k (undefined :: Z)
reifyTypeNat a k | a > 0 = reifyTypeNat (a - 1) (\(_ :: b) -> k (undefined :: S b))
| a < 0 =undefined