Files
school_archives/OSU Coursework/CS 381 - Programming Language Fundamentals/Homework 1/Nat.perrenc.hs

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