Skip to content

Instantly share code, notes, and snippets.

@qexat
Last active July 5, 2025 22:01
Show Gist options
  • Select an option

  • Save qexat/537685b90ebb29ba2de87ed6f6f17249 to your computer and use it in GitHub Desktop.

Select an option

Save qexat/537685b90ebb29ba2de87ed6f6f17249 to your computer and use it in GitHub Desktop.
Nat in Haskell
data Nat where
O :: Nat
S :: Nat -> Nat
instance Eq Nat where
(==) O O = True
(==) O (S _) = False
(==) (S _) O = False
(==) (S n) (S m) = n == m
instance Num Nat where
(+) n O = n
(+) O m = m
(+) n (S m) = S n + m
(-) n O = n
(-) O _ = O
(-) (S n) (S m) = n - m
(*) _ O = O
(*) O _ = O
(*) n (S m) = n + n * m
abs n = n
signum O = O
signum (S _) = S O
fromInteger i = if i <= 0 then O else S (fromInteger (i - 1))
instance Show Nat where
show O = "O"
show (S O) = "S O"
show (S n) = "S (" ++ show n ++ ")"
fix :: ((a -> b) -> a -> b) -> a -> b
fix f x = f (fix f) x
fact :: Nat -> Nat
fact = fix $ \fact n ->
case n of
O -> S O
S n' -> n * fact n'
main = putStrLn (show $ fact (fromInteger 3))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment