This chapter focus on the different syntax we can use with functions
map data to a specific pattern and deconstruct the data.
For each data you want to match you can define a specific body for the same function:
myFunc :: Integer -> Integer
myFunc 42 = 42
myFunc x = 0Pattern matching can be applied to different type of data
Tuple
multByTwo :: (Integer, Integer) -> (Integer, Integer)
multByTwo (a,b) = (a * 2, b * 2 )List comprehension [a+b | (a,b) <- xs]
**List**
```haskell
[]
(x:[])
(x:xs)
(x:y:ys)
l@(x:xs) This syntax is called "as pattern" and give the name l to the patter (x:xs)
Expressions are evaluated from the top to the bottom. So the order is very important! Check that you define a catch-all pattern!
Guards test values to True or False. Looks like a if expression
isOdd :: Integer -> String
isOdd n
| odd n = "It's odd"
| otherwise = "It's not!"otherwise is the catch-all pattern.
where give a names to an expressions
Block where at the end guards:
bmiTell :: (RealFloat a) => a -> a -> String
bmiTell 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 = 18.5
normal = 25.0
fat = 30.0Block where attached to a function
calcBmis :: (RealFloat a) => [(a, a)] -> [a]
calcBmis xs = [bmi w h | (w, h) <- xs]
where bmi weight height = weight / height ^ 2Names defined in the where block are only visible in the local scope of the guards or functions
Where block can be nested
Let is similar to where but it can let you bind name to expression anywhere
syntax: let in . Expressions define in bindings are accessible in the in part.
In the middle of nowhere:
4 * (let a = 9 in a + 1) + 2In function:
cylinder :: (RealFloat a) => a -> a -> a
cylinder r h =
let sideArea = 2 * pi * r * h
topArea = pi * r ^2
in sideArea + 2 * topAreain a lis:
[let square x = x * x in (square 5, square 3, square 2)]in list comprehension (don't need the in part)
calcBmis :: (RealFloat a) => [(a, a)] -> [a]
calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2] The main difference between Where and Let is that where is a syntaxic construc, let is an expression. The scope of let is very local and won't spread around guard for example.
It's a case.
case expression of pattern -> result
pattern -> result
pattern -> result
...