-
Notifications
You must be signed in to change notification settings - Fork 3
/
syntax.hs
143 lines (114 loc) · 4.5 KB
/
syntax.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
-- pattern matching
lucky :: (Integral a) => a -> String
lucky 7 = "LUCKY NUMBER SEVEN!"
lucky x = "Sorry, you're out of luck, pal!"
sayMe :: (Integral a) => a -> String
sayMe 1 = "One!"
sayMe 2 = "Two!"
sayMe 3 = "Three!"
sayMe 4 = "Four!"
sayMe 5 = "Five!"
sayMe x = "Not between 1 and 5"
-- pattern matching using recursion
factorial :: (Integral a) => a -> a
factorial 0 = 1
factorial n = n * factorial (n - 1)
-- exhaustiveness check (try it by calling chaName 'd')
charName :: Char -> String
charName 'a' = "Albert"
charName 'b' = "Broseph"
charName 'c' = "Cecil"
-- add two vectors without and with pattern matching
addVectorsNoPM :: (Num a) => (a, a) -> (a, a) -> (a, a)
addVectorsNoPM a b = (fst a + fst b, snd a + snd b)
addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a) -- Try it with addVectors (1,2) (6,7)
addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)
-- define triple using pm
first :: (a, b, c) -> a
first (x, _, _) = x
second :: (a, b, c) -> b
second (_, y, _) = y
third :: (a, b, c) -> c
third (_, _, z) = z
-- pm on lists
--xs = [(1,3), (4,3), (2,4), (5,3), (5,6), (3,1)]
--sumPairs = [a+b | (a,b) <- xs]
sumPairs :: (Num a) => [(a,a)] -> [a] -- evidence that a is a Num
sumPairs xs = [x+y | (x,y) <- xs]
-- defining our own head function
head' :: [a] -> a
head' [] = error "Can't call head on an empty list, dummy!"
head' (x:_) = x
-- using Show evidence
tell :: (Show a) => [a] -> String
tell [] = "The list is empty"
tell (x:[]) = "The list has one element: " ++ show x -- syntax sugar is: tell [x] = ...
tell (x:y:[]) = "The list has two elements: " ++ show x ++ " and " ++ show y -- syntax sugar is: tell [x,y] = ...
tell (x:y:_) = "This list is long. The first two elements are: " ++ show x ++ " and " ++ show y
-- using pm and recursion
length' :: (Num b) => [a] -> b
length' [] = 0
length' (_:xs) = 1 + length' xs
sum' :: (Num a) => [a] -> a
sum' [] = 0
sum' (x:xs) = x + sum' xs
-- 'as patterns' binding
capital :: String -> String
capital "" = "Empty string, whoops!"
capital all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x]
-------- guards
bmiTell :: (RealFloat a) => a -> String
bmiTell bmi
| bmi <= 18.5 = "You're underweight, you emo, you!"
| bmi <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!"
| bmi <= 30.0 = "You're fat! Lose some weight, fatty!"
| otherwise = "You're a whale, congratulations!"
bmiTell2 :: (RealFloat a) => a -> a -> String
bmiTell2 weight height
| bmi <= skinny = "You're underweight, you emo, you!"
| bmi <= normal = "You're supposedly normal. Pffft, I bet you're ugly!"
| bmi <= fat = "You're fat! Lose some weight, fatty!"
| otherwise = "You're a whale, congratulations!"
where bmi = weight / height ^ 2
(skinny, normal, fat) = (18.5, 25.0, 30.0)
max' :: (Ord a) => a -> a -> a
max' a b | a > b = a | otherwise = b
-- using backsticks ``
myCompare :: (Ord a) => a -> a -> Ordering -- try it with: 3 `myCompare` 2
a `myCompare` b
| a > b = GT
| a == b = EQ
| otherwise = LT
-- using where in pm
initials :: String -> String -> String
initials firstname lastname = [f] ++ ". " ++ [l] ++ "."
where (f:_) = firstname
(l:_) = lastname
calcBmis :: (RealFloat a) => [(a, a)] -> [a]
calcBmis xs = [bmi w h | (w, h) <- xs]
where bmi weight height = weight / height ^ 2
-- let bindings
cylinder :: (RealFloat a) => a -> a -> a
cylinder r h =
let sideArea = 2 * pi * r * h
topArea = pi * r ^2
in sideArea + 2 * topArea
-- 4 * (let a = 9 in a + 1) + 2
-- [let square x = x * x in (square 5, square 3, square 2)]
-- (let (a,b,c) = (1,2,3) in a+b+c) * 100
-- let inside lists comprehension and filtering
calcBmisFilter :: (RealFloat a) => [(a, a)] -> [a]
calcBmisFilter xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2, bmi >= 25.0]
------------ case expresions (pattern matching is a syntax sugar for it)
head2 :: [a] -> a
head2 xs = case xs of [] -> error "No head for empty lists!"
(x:_) -> x
describeList :: [a] -> String
describeList xs = "The list is " ++ case xs of [] -> "empty."
[x] -> "a singleton list."
xs -> "a longer list."
describeList2 :: [a] -> String
describeList2 xs = "The list is " ++ what xs
where what [] = "empty."
what [x] = "a singleton list."
what xs = "a longer list."