-
Notifications
You must be signed in to change notification settings - Fork 0
/
Nat.egleyb.hs
175 lines (147 loc) · 2.63 KB
/
Nat.egleyb.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
-- | Team Members: Bryce Egley ONID: egleyb, Kenneth Price ONID: pricek, Kenneth Thompson ONID: thomkenn
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 n) = n
-- | True if the given value is zero.
--
-- >>> isZero Zero
-- True
--
-- >>> isZero two
-- False
--
isZero :: Nat -> Bool
isZero Zero = True
isZero (n) = False
-- | Convert a natural number to an integer.
--
-- >>> toInt Zero
-- 0
--
-- >>> toInt three
-- 3
--
toInt :: Nat -> Int
toInt Zero = 0
toInt (Succ n) = 1 + toInt n
-- | 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 n2 = n2
add n1 n2 = add (pred n1) (Succ n2)
-- | 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 n2 Zero = Zero
sub Zero n1 = n1
sub n2 n1 = sub (pred n1) (pred n2)
-- | 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 n2 n1 = not (sub n2 n1 == Zero)
-- | 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 (Succ Zero) n2 = n2
mult n1 n2 = add n2 (mult (pred n1) n2)
-- | 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 (i:t) = add i (sum t)
-- | 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