{-# LANGUAGE TypeFamilies, GADTs, UndecidableInstances, NoImplicitPrelude #-}
module Data.Category.NNO where
import Data.Kind (Type)
import Data.Category.Functor
import Data.Category.Limit
import Data.Category.Unit
import Data.Category.Coproduct
import Data.Category.Fix (Fix(..))
class HasTerminalObject k => HasNaturalNumberObject k where
type NaturalNumberObject k :: Type
zero :: k (TerminalObject k) (NaturalNumberObject k)
succ :: k (NaturalNumberObject k) (NaturalNumberObject k)
primRec :: k (TerminalObject k) a -> k a a -> k (NaturalNumberObject k) a
data NatNum = Z | S NatNum
instance HasNaturalNumberObject (->) where
type NaturalNumberObject (->) = NatNum
zero :: TerminalObject (->) -> NaturalNumberObject (->)
zero = \() -> NatNum
Z
succ :: NaturalNumberObject (->) -> NaturalNumberObject (->)
succ = NatNum -> NatNum
S
primRec :: forall a.
(TerminalObject (->) -> a)
-> (a -> a) -> NaturalNumberObject (->) -> a
primRec TerminalObject (->) -> a
z a -> a
_ NatNum
NaturalNumberObject (->)
Z = TerminalObject (->) -> a
z ()
primRec TerminalObject (->) -> a
z a -> a
s (S NatNum
n) = a -> a
s (forall (k :: * -> * -> *) a.
HasNaturalNumberObject k =>
k (TerminalObject k) a -> k a a -> k (NaturalNumberObject k) a
primRec TerminalObject (->) -> a
z a -> a
s NatNum
n)