mirror of
https://github.com/caperren/school_archives.git
synced 2025-11-09 13:41:13 +00:00
173 lines
2.6 KiB
Haskell
173 lines
2.6 KiB
Haskell
module Nat where
|
|
|
|
import Prelude hiding (Enum(..), sum)
|
|
|
|
|
|
--
|
|
-- * Part 2: Natural numbers
|
|
--
|
|
|
|
-- | The natural numbers.
|
|
data Nat = Zero
|
|
| Succ Nat
|
|
deriving (Eq,Show)
|
|
|
|
-- | The number 1.
|
|
one :: Nat
|
|
one = Succ Zero
|
|
|
|
-- | The number 2.
|
|
two :: Nat
|
|
two = Succ one
|
|
|
|
-- | The number 3.
|
|
three :: Nat
|
|
three = Succ two
|
|
|
|
-- | The number 4.
|
|
four :: Nat
|
|
four = Succ three
|
|
|
|
|
|
-- | The predecessor of a natural number.
|
|
--
|
|
-- >>> pred Zero
|
|
-- Zero
|
|
--
|
|
-- >>> pred three
|
|
-- Succ (Succ Zero)
|
|
--
|
|
pred :: Nat -> Nat
|
|
pred Zero = Zero
|
|
pred (Succ nat) = nat
|
|
|
|
-- | True if the given value is zero.
|
|
--
|
|
-- >>> isZero Zero
|
|
-- True
|
|
--
|
|
-- >>> isZero two
|
|
-- False
|
|
--
|
|
isZero :: Nat -> Bool
|
|
isZero x = x == Zero
|
|
|
|
|
|
-- | Convert a natural number to an integer.
|
|
--
|
|
-- >>> toInt Zero
|
|
-- 0
|
|
--
|
|
-- >>> toInt three
|
|
-- 3
|
|
--
|
|
toInt :: Nat -> Int
|
|
toInt Zero = 0
|
|
toInt (Succ nat) = (toInt nat) + 1
|
|
|
|
|
|
-- | Add two natural numbers.
|
|
--
|
|
-- >>> add one two
|
|
-- Succ (Succ (Succ Zero))
|
|
--
|
|
-- >>> add Zero one == one
|
|
-- True
|
|
--
|
|
-- >>> add two two == four
|
|
-- True
|
|
--
|
|
-- >>> add two three == add three two
|
|
-- True
|
|
--
|
|
add :: Nat -> Nat -> Nat
|
|
add Zero x = x
|
|
add (Succ nat) x = add nat (Succ x)
|
|
|
|
|
|
-- | Subtract the second natural number from the first. Return zero
|
|
-- if the second number is bigger.
|
|
--
|
|
-- >>> sub two one
|
|
-- Succ Zero
|
|
--
|
|
-- >>> sub three one
|
|
-- Succ (Succ Zero)
|
|
--
|
|
-- >>> sub one one
|
|
-- Zero
|
|
--
|
|
-- >>> sub one three
|
|
-- Zero
|
|
--
|
|
sub :: Nat -> Nat -> Nat
|
|
sub Zero _ = Zero
|
|
sub x Zero = x
|
|
sub (Succ x) (Succ y) = sub x y
|
|
|
|
|
|
-- | Is the left value greater than the right?
|
|
--
|
|
-- >>> gt one two
|
|
-- False
|
|
--
|
|
-- >>> gt two one
|
|
-- True
|
|
--
|
|
-- >>> gt two two
|
|
-- False
|
|
--
|
|
gt :: Nat -> Nat -> Bool
|
|
gt Zero Zero = False
|
|
gt Zero (Succ _) = False
|
|
gt (Succ _) Zero = True
|
|
gt (Succ x) (Succ y) = gt x y
|
|
|
|
|
|
-- | Multiply two natural numbers.
|
|
--
|
|
-- >>> mult two Zero
|
|
-- Zero
|
|
--
|
|
-- >>> mult Zero three
|
|
-- Zero
|
|
--
|
|
-- >>> toInt (mult two three)
|
|
-- 6
|
|
--
|
|
-- >>> toInt (mult three three)
|
|
-- 9
|
|
--
|
|
mult :: Nat -> Nat -> Nat
|
|
mult Zero _ = Zero
|
|
mult _ Zero = Zero
|
|
mult x (Succ y) = add x (mult x y)
|
|
|
|
|
|
-- | Compute the sum of a list of natural numbers.
|
|
--
|
|
-- >>> sum []
|
|
-- Zero
|
|
--
|
|
-- >>> sum [one,Zero,two]
|
|
-- Succ (Succ (Succ Zero))
|
|
--
|
|
-- >>> toInt (sum [one,two,three])
|
|
-- 6
|
|
--
|
|
sum :: [Nat] -> Nat
|
|
sum [] = Zero
|
|
sum (x:xs) = add x (sum xs)
|
|
|
|
|
|
-- | An infinite list of all of the *odd* natural numbers, in order.
|
|
--
|
|
-- >>> map toInt (take 5 odds)
|
|
-- [1,3,5,7,9]
|
|
--
|
|
-- >>> toInt (sum (take 100 odds))
|
|
-- 10000
|
|
--
|
|
odds :: [Nat]
|
|
odds = one : map (add two) odds
|