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)