:{ data Nat = Z | S Nat deriving (Show, Eq, Ord) instance Num Nat where Z + n = n S m + n = S (m + n) Z * _ = Z S m * n = n + m * n negate _ = error "negate on Nat" abs = id signum Z = Z signum _ = 1 fromInteger n | n < 0 = error "fromInteger to Nat on negative number" | otherwise = let go 0 = Z go m = S (go (m-1)) in go n :}