-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexercises.hs
94 lines (71 loc) · 2.26 KB
/
exercises.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
-- Exercises for Learn Haskell By Example
-- These are exercises that aren't part of the projects
--
-- Chapter 4
--
-- Implement lines, unlines, words, unwords
-- unlines and unwords behave identically, except for the different separator, so write a
-- general splitting function
splitOn :: Char -> String -> [String]
splitOn ch str =
let go :: String -> String -> [String]
go acc [] = [acc]
go acc (c : cs)
| c == ch = acc : go [] cs
| otherwise = go (acc <> [c]) cs
in go [] str
myLines :: String -> [String]
myLines = splitOn '\n'
myWords :: String -> [String]
myWords = splitOn ' '
-- unlines adds '\n' as the end of the string, while unwords doesn't add a space. So need to write
-- separate functions
myUnlines :: [String] -> String
myUnlines [] = ""
myUnlines (x : xs) = x <> "\n" <> myUnlines xs
myUnwords :: [String] -> String
myUnWords [] = ""
myUnwords (x : xs)
| null xs = x
| otherwise = x <> " " <> myUnwords xs
-- Implement zipWith and use it to define zip
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x : xs) (y : ys) = f x y : zipWith' f xs ys
zip' :: [a] -> [b] -> [(a,b)]
zip' = zipWith' (,)
-- Implement mapM and mapM_
mapM' :: (a -> IO b) -> [a] -> IO [b]
mapM' f as =
let go acc ys = do
case ys of
[] -> return acc
(x : xs) -> do
b <- f x
go (b : acc) xs
in go [] as
mapM_' :: (a -> IO b) -> [a] -> IO ()
mapM_' _ [] = return ()
mapM_' f (x : xs) = do
f x
mapM_' f xs
--
-- Chapter 5
--
-- Implement member with lookup
member :: Eq a => a -> [(a,b)] -> Bool
member x xs =
case lookup x xs of
Nothing -> False
Just _ -> True
-- Implement alter with maybe
alter :: Eq k => (Maybe v -> Maybe v) -> k -> [(k, v)]-> [(k, v)]
alter f key [] = maybe [] (\value -> [(key, value)]) (f Nothing)
alter f key ((key', value') : xs)
| key == key' = maybe xs (\value -> (key, value) : xs) (f (Just value'))
| otherwise = (key', value') : alter f key xs
-- High order function to implment addEdges and buildDiGraph, i.e., write foldr
myFoldr :: (a -> b -> b) -> b -> [a] -> b
myFoldr f x [] = x
myFoldr f x (y : ys) = f y (myFoldr f x ys)