-
Notifications
You must be signed in to change notification settings - Fork 1
/
ch12.hs
99 lines (76 loc) · 2.32 KB
/
ch12.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
module Ch12 where
notThe :: String -> Maybe String
notThe word = case word == "the" of
True -> Nothing
otherwise -> Just word
replaceThe :: String -> String
replaceThe text = foldl (++) "" (f maybes)
where maybes = map notThe $ words text
f [Just w] = [w]
f [Nothing] = ["a"]
f ((Just w) : ws) = (w ++ " ") : f ws
f (Nothing : ws) = "a " : f ws
f _ = []
countTheBeforeVowel :: String -> Integer
countTheBeforeVowel s =
case words s of
[] -> 0
[w] -> 0
ws ->
let
classifiedWords = map classify ws
count (IsThe, StartsWithVowel) acc = 1 + acc
count _ acc = acc
in
foldr count 0 $ zip classifiedWords (tail classifiedWords)
data Classification = IsThe | StartsWithVowel | SomethingElse
classify :: String -> Classification
classify s
| s == "the" = IsThe
| startsWithVowel s = StartsWithVowel
| otherwise = SomethingElse
startsWithVowel :: String -> Bool
startsWithVowel [] = False
startsWithVowel (c:cs) = isVowel c
isVowel :: Char -> Bool
isVowel c = c `elem` "aeiou"
countVowels :: String -> Integer
countVowels = go 0
where go acc [] = acc
go acc (c:cs) = go (acc + r) cs where r = if isVowel c then 1 else 0
data Nat = Zero | Succ Nat deriving (Eq, Show)
natToInteger :: Nat -> Integer
natToInteger Zero = 0
natToInteger (Succ n) = 1 + natToInteger n
integerToNat :: Integer -> Maybe Nat
integerToNat k
| k < 0 = Nothing
| otherwise = Just (go k)
where
go 0 = Zero
go k = Succ (go $ k - 1)
myIterate :: (a -> a) -> a -> [a]
myIterate f a = a : myIterate f (f a)
myUnfoldr :: (b -> Maybe (a, b)) -> b -> [a]
myUnfoldr f b =
let
go Nothing acc = acc
go (Just (a, b')) acc = a : go (f b') acc
in
go (f b) []
betterIterate :: (a -> a) -> a -> [a]
betterIterate f x = myUnfoldr (\a -> Just (a, f a)) x
data BinaryTree a
= Leaf
| Node (BinaryTree a) a (BinaryTree a)
deriving (Eq, Ord, Show)
unfold :: (a -> Maybe (a,b,a)) -> a -> BinaryTree b
unfold f a =
case f a of
Nothing -> Leaf
Just (l, m, r) -> Node (unfold f l) m (unfold f r)
treeBuild :: Integer -> BinaryTree Integer
treeBuild n
| n < 0 = Leaf
| otherwise = unfold f 0
where f k = if (k == n) then Nothing else Just (k + 1, k, k + 1)