module Data.Natural.Class where
import Prelude hiding (iterate)
import Data.Functor.Const
import Data.Peano
import Data.Proxy
class Natural n where
natural :: f Zero -> (∀ m . Natural m => f (Succ m)) -> f n
instance Natural Zero where
natural zf _ = zf
instance Natural n => Natural (Succ n) where
natural _ sf = sf
reify :: Natural n => Const Peano n
reify = iterate Succ Zero
iterate :: ∀ n a . Natural n => (a -> a) -> a -> Const a n
iterate f a = natural (Const a) (f' (iterate f a))
where f' = Const . f . getConst :: ∀ n . Const a n -> Const a (Succ n)