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