-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtutorial3.hs
180 lines (126 loc) · 3.95 KB
/
tutorial3.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
-- Informatics 1 - Functional Programming
-- Tutorial 3
--
-- Week 5 - Due: 22/23 Oct.
import Data.Char
import Data.List
import Test.QuickCheck
-- 1. Map
-- a.
uppers :: String -> String
uppers text = map (toUpper) text
-- b.
doubles :: [Int] -> [Int]
doubles xs = map (*2) xs
-- c.
penceToPounds :: [Int] -> [Float]
penceToPounds xs = map (\x -> fromIntegral x / 100) xs
-- d.
uppers' :: String -> String
uppers' text = [toUpper character | character <- text]
prop_uppers :: String -> Bool
prop_uppers text = uppers text == uppers' text
-- 2. Filter
-- a.
alphas :: String -> String
alphas text = filter isAlpha text
-- b.
rmChar :: Char -> String -> String
rmChar char text = filter (\x -> x /= (toLower char) && x /= (toUpper char)) text
-- c.
above :: Int -> [Int] -> [Int]
above least numbers = filter (\x -> x > least) numbers
-- d.
unequals :: [(Int,Int)] -> [(Int,Int)]
unequals pairs = filter (\(x,y) -> x /= y) pairs
-- e.
rmCharComp :: Char -> String -> String
rmCharComp char text = [textChar | textChar <- text, textChar /= toLower char, textChar /= toUpper char]
prop_rmChar :: Char -> String -> Bool
prop_rmChar char text = rmChar char text == rmCharComp char text
-- 3. Comprehensions vs. map & filter
-- a.
upperChars :: String -> String
upperChars s = [toUpper c | c <- s, isAlpha c]
upperChars' :: String -> String
upperChars' text = filter (isAlpha) $ map (toUpper) text
prop_upperChars :: String -> Bool
prop_upperChars s = upperChars s == upperChars' s
-- b.
largeDoubles :: [Int] -> [Int]
largeDoubles xs = [2 * x | x <- xs, x > 3]
largeDoubles' :: [Int] -> [Int]
largeDoubles' xs = map (*2) $ filter (\x -> x > 3) xs
prop_largeDoubles :: [Int] -> Bool
prop_largeDoubles xs = largeDoubles xs == largeDoubles' xs
-- c.
reverseEven :: [String] -> [String]
reverseEven strs = [reverse s | s <- strs, even (length s)]
reverseEven' :: [String] -> [String]
reverseEven' strs = map (reverse) $ filter (\x -> even $ length x) strs
prop_reverseEven :: [String] -> Bool
prop_reverseEven strs = reverseEven strs == reverseEven' strs
-- 4. Foldr
-- a.
productRec :: [Int] -> Int
productRec [] = 1
productRec (x:xs) = x * productRec xs
productFold :: [Int] -> Int
productFold numbers = foldr (*) 1 numbers
prop_product :: [Int] -> Bool
prop_product xs = productRec xs == productFold xs
-- b.
andRec :: [Bool] -> Bool
andRec [] = True
andRec (x:xs) = x && andRec xs
andFold :: [Bool] -> Bool
andFold xs = foldr (&&) True xs
prop_and :: [Bool] -> Bool
prop_and xs = andRec xs == andFold xs
-- c.
concatRec :: [[a]] -> [a]
concatRec [] = []
concatRec (element:list) = element ++ concatRec list
concatFold :: [[a]] -> [a]
concatFold list = foldr (++) [] list
prop_concat :: [String] -> Bool
prop_concat strs = concatRec strs == concatFold strs
-- d.
rmCharsRec :: String -> String -> String
rmCharsRec _ [] = []
rmCharsRec [] text2 = text2
rmCharsRec (char:text1) text2 = rmCharsRec text1 $ rmChar char text2
rmCharsFold :: String -> String -> String
rmCharsFold text1 text2 = foldr (rmChar) text2 text1
prop_rmChars :: String -> String -> Bool
prop_rmChars chars str = rmCharsRec chars str == rmCharsFold chars str
type Matrix = [[Int]]
-- 5
-- a.
uniform :: [Int] -> Bool
uniform matrix = all (\x -> x == matrix !! 0) matrix
-- b.
valid :: Matrix -> Bool
valid [] = False
valid matrix = uniform [length x | x <- matrix]
-- 6.
-- a) 18
-- b)
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' func list1 list2 = [func x y | (x,y) <- zip list1 list2]
-- c)
zipWith'' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith'' function list1 list2 = map (uncurry function) $ zip list1 list2
-- 7.
plusM :: Matrix -> Matrix -> Matrix
plusM m1 m2 = zipWith (addRows) m1 m2
where addRows xs ys = zipWith (+) xs ys
-- 8.
-- dot product
dot :: [Int] -> [Int] -> Int
dot vector1 vector2 = sum $ zipWith (*) vector1 vector2
timesM :: Matrix -> Matrix -> Matrix
timesM m1 m2 = [[dot rows cols | cols <- transpose m2]
| rows <- m1]
-- Optional material
-- 9.