data Nat = Zero | Succ Nat deriving (Show, Eq) instance Num Nat where n + Zero = n n + (Succ m) = Succ (n + m) Zero - _ = Zero n - Zero = n (Succ n) - (Succ m) = n - m n * Zero = Zero n * (Succ m) = n + (n * m) negate = const Zero abs = id signum = id fromInteger i = if i > 0 then Succ (fromInteger (i-1)) else Zero instance Ord Nat where Zero <= b = True _ <= Zero = False (Succ n) <= (Succ b) = n <= b instance Enum Nat where toEnum = fromInteger . toInteger fromEnum Zero = 0 fromEnum (Succ n) = 1 + (fromEnum n) -- yet "(2::Nat) <= product [2..]" does not terminate.