-
Notifications
You must be signed in to change notification settings - Fork 0
/
Answers.hs
255 lines (201 loc) · 4.29 KB
/
Answers.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
import Prelude hiding ((++), (!!), all, any, concat, drop, filter, find, foldl, foldr, head, length, map, reverse, tail, take, zip)
--
-- ghci> :i []
-- data [] a = [] | a : [a] -- Defined in ‘GHC.Types’
--
head :: [a] -> a
head list =
case list of
[] -> error "empty list"
x : xs -> x
headMaybe :: [a] -> Maybe a
headMaybe list =
case list of
[] -> Nothing
x : xs -> Just x
tail :: [a] -> [a]
tail list =
case list of
[] -> error "empty list"
x : xs -> xs
tailMaybe :: [a] -> Maybe ([a])
tailMaybe list =
case list of
[] -> Nothing
x : xs -> Just xs
length :: [a] -> Int
length list =
case list of
[] -> 0
x : xs -> 1 + (length xs)
lengthTCO :: [a] -> Int
lengthTCO list =
let
loop list count =
case list of
[] -> count
x : xs -> loop xs (count + 1)
in
loop list 0
(!!) :: [a] -> Int -> a
list !! index =
if index < 0
then error "negative index"
else
case list of
[] -> error "index too large"
x : xs ->
if index == 0
then x
else xs !! (index - 1)
map :: (a -> b) -> [a] -> [b]
map fn list =
case list of
[] -> []
x : xs -> (fn x) : (map fn xs)
mapTCO :: (a -> b) -> [a] -> [b]
mapTCO fn list =
let
loop list result =
case list of
[] -> reverse result
x : xs -> loop xs ((fn x) : result)
in
loop list []
find :: (a -> Bool) -> [a] -> Maybe a
find predicate list =
case list of
[] -> Nothing
x : xs ->
if predicate x
then Just x
else find predicate xs
filter :: (a -> Bool) -> [a] -> [a]
filter predicate list =
case list of
[] -> []
x : xs ->
if predicate x
then x : (filter predicate xs)
else filter predicate xs
filterTCO :: (a -> Bool) -> [a] -> [a]
filterTCO predicate list =
let
loop list result =
case list of
[] -> reverse result
x : xs -> loop xs (if predicate x then x : result else result)
in
loop list []
all :: (a -> Bool) -> [a] -> Bool
all predicate list =
case list of
[] -> True
x : xs ->
if predicate x
then all predicate xs
else False
any :: (a -> Bool) -> [a] -> Bool
any predicate list =
case list of
[] -> False
x : xs ->
if predicate x
then True
else any predicate xs
concat :: [[a]] -> [a]
concat lists =
case lists of
[] -> []
xs : xss -> xs ++ (concat xss)
concatTCO :: [[a]] -> [a]
concatTCO lists =
let
loop lists result =
case lists of
[] -> result
xs : xss -> loop xss (result ++ xs)
in
loop lists []
take :: Int -> [a] -> [a]
take n list =
case list of
[] -> []
x : xs ->
if n == 0
then []
else x : (take (n - 1) xs)
takeTCO :: Int -> [a] -> [a]
takeTCO n list =
let
loop list n result =
case list of
[] -> reverse result
x : xs ->
if n == 0
then reverse result
else loop xs (n - 1) (x : result)
in
loop list n []
drop :: Int -> [a] -> [a]
drop n list =
case list of
[] -> []
x : xs ->
if n == 0
then list
else drop (n - 1) xs
zip :: [a] -> [b] -> [(a, b)]
zip xs ys =
case (xs, ys) of
([], _) -> []
(_, []) -> []
(x : xs, y : ys) -> (x, y) : (zip xs ys)
zipTCO :: [a] -> [b] -> [(a,b)]
zipTCO xs ys =
let
loop xs ys result =
case (xs, ys) of
([], _) -> reverse result
(_, []) -> reverse result
(x : xs, y : ys) -> loop xs ys ((x, y) : result)
in
loop xs ys []
(++) :: [a] -> [a] -> [a]
xs ++ ys =
case xs of
[] -> ys
x : xs -> x : (xs ++ ys)
appendTCO :: [a] -> [a] -> [a]
appendTCO xs ys =
let
loop ys result =
case ys of
[] -> reverse result
y : ys -> loop ys (y : result)
in
loop ys (reverse xs)
reverse :: [a] -> [a]
reverse list =
case list of
[] -> []
x : xs -> reverse xs ++ [x]
reverseTCO :: [a] -> [a]
reverseTCO xs =
let
loop xs result =
case xs of
[] -> result
x : xs -> loop xs (x : result)
in
loop xs []
foldl :: (b -> a -> b) -> b -> [a] -> b
foldl fn seed list =
case list of
[] -> seed
x : xs -> foldl fn (fn seed x) xs
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr fn seed list =
case list of
[] -> seed
x : xs -> fn x (foldr fn seed xs)