— CPSC 312 2021 – Assignment 2 solution
— Copyright D. Poole, 2021. Do not redistrubute
— Question 1 (a)
tails :: [t] -> [[t]]
tails [] = [[]]
tails (e:r) = (e:r):tails(r)
— *Main> tails “happy”
— [“happy”,”appy”,”ppy”,”py”,”y”,””]
— *Main> :type tails “happy”
— tails “happy” :: [[Char]]
tails1 :: [t] -> [[t]]
tails1 = foldr (\e (hr:rr) -> (e:hr):(hr:rr) ) [[]]
— Question 1(b)
doif f g [] = []
doif f g (h:t)
| f h = g h : doif f g t
| otherwise = h : doif f g t
— (i)
— :type doif
doif :: (t -> Bool) -> (t -> t) -> [t] -> [t]
— (ii)
–doif even (`div` 2) [11,22,33,44,55,66]
— [11,11,33,22,55,33]
— (iii)
capvowel lst = doif (`elem` “aeiou”) toUpper lst
toUpper :: Char -> Char
toUpper x = toEnum( fromEnum x – fromEnum ‘a’ + fromEnum ‘A’)
— (iv)
doif1 f g lst = [if f x then g x else x | x <- lst]
-- doif1 even (`div` 2) [11,22,33,44,55,66]
-- (v)
doif2 f g = foldr (\x y -> (if f x then g x else x):y) []
— doif2 even (`div` 2) [11,22,33,44,55,66]
— Question 2
— 2(a) Using foldr
harmonic n = foldr (+) 0 [1/i | i <- [1..n]]
harmonic1 n = foldr (\x y -> 1/x+y) 0 [1..n]
— Using foldl
harmonic3 n = foldl (+) 0 [1/i | i <- [1..n]]
harmonic4 n = foldl (\x y -> x+1/y) 0 [1..n]
— 2(b)
myremoveduplicates :: Eq t => [t] -> [t]
myremoveduplicates = foldr (\ e r -> if e `elem` r then r else e:r) []
myremoveduplicates1 lst = [ head l | l <- tails lst, l /= [], not (head l `elem` tail l)]
myremoveduplicates2 lst = [ h | (h:t) <- tails lst, not (h `elem` t)] --using pattern matching
-- myremoveduplicates "abacad"
-- myremoveduplicates2 [7,3,2,1,3,2,2,1,1,3,7,8]
-- 2(c)
myordered lst = and [e1<=e2 | (e1:e2:r) <- tails lst]
-- myordered "abcdefg"
-- myordered "ba"
---or using zip (which you should define yourself)
myordered2 [] = True
myordered2 (h:t) = and [e1 <= e2 | (e1,e2) <- zip (h:t) t]
-- 2(d)
myreplace x y lst = [if e==x then y else e | e <- lst]
-- myreplace 7 3 [7,0,7,1,7,2,7,3]
-- myreplace 'a' 'x' ""
-- myreplace 'a' 'x' "abacad"
-- 2(e)
-- one try
myapply lst sub = [(\res -> if res /= [] then head res else e) [b | (a,b) <- sub, a==e] | e <- lst]
-- myapply "abcdec" [('a','f'), ('c','3'), ('g','7')]
-- myapply "baab" [('a','b'), ('b','a')]
-- or even clearer....
-- head_with_default lst def = head of list lst, otherwise (if there is no head) evaluates to def
myapply1 lst sub = [head_with_default [b | (a,b) <- sub, a==e] e | e <- lst]
where
head_with_default [] def = def
head_with_default (h:t) _ = h
-- or even simpler
myapply2 lst sub = [head [b | (a,b) <- sub++[(e,e)], a==e] | e <- lst]