1
1
mirror of https://github.com/thma/WhyHaskellMatters.git synced 2024-10-26 14:32:24 +03:00

pattern matching

This commit is contained in:
Mahler, Thomas 2020-03-28 21:28:42 +01:00
parent e5f3012594
commit 151c428e04

View File

@ -357,33 +357,41 @@ With the things that we have learnt so far, we can now start to implement some m
So what about implementing the recursive [factorial function](https://en.wikipedia.org/wiki/Factorial)?
The factorial function can be defined as follows:
```
0! = 1
n! = n * (n-1)!
for all n ∈ <sub>0</sub>
```
> For all n ∈ <sub>0</sub>:
>```
>0! = 1
>n! = n * (n-1)!
>```
With our current knowledge of Haskell we can implement this as follows:
```haskell
factorial :: Natural -> Natural -- Natural is a data type representing all non-negative integers
factorial :: Natural -> Natural
factorial n =
if n == 0
then 1
else n * factorial (n - 1)
```
We are using the data type `Natural` to denote the set of non-negative integers
We are using the Haskell data type `Natural` to denote the set of non-negative integers <sub>0</sub>.
Using the literal `factorial` within the definition of the function `factorial` works as expected and denotes a
recursive function call.
As these kind of recursive definition of functions are typical for functional programming, the language designers have
added a useful feature called *pattern matching* that allows to define functions by a set of equations:
```haskell
-- definition of factorial using pattern matching
fac :: Natural -> Natural
fac 0 = 1
fac n = n * fac (n - 1)
```
This style comes much closer to the mathematical definition and is typically more readable, as it helps to avoid
nested `if ... then ... else ...` constructs.
Pttern matching can not only be used for numeric values but for any other data types. We'll see some more examples shortly.
## Dealing with Lists
Working with lists or other kinds of collections is a typical business in many problem domains that software developers
@ -392,6 +400,35 @@ have to deal with.
Support for lists is provided by the Haskell base library and there is also some syntactic sugar built into the
language that makes working with lists quite a pleasant experience.
A List can either be the empty list (denoted by `[]`) or some element (of any data type) followed by a list.
So a list containing only a single element `1` is represented by:
```haskell
1 : []
```
A list containing the three numbers 1, 2, 3 is contructed like this:
```haskell
1 : 2 : 3 : []
```
Luckily the language designers have been so kind to offer some syntactic sugar for this. So the first list can be
written as `[1]` and the second as `[1, 2, 3]`.
```haskell
-- | Extract the first element of a list, which must be non-empty.
head :: [a] -> a
head (x:_) = x
head [] = error "head: empty list"
-- | Extract the elements after the head of a list, which must be non-empty.
tail :: [a] -> [a]
tail (_:xs) = xs
tail [] = error "tail: empty list"
```
Let's start by defining a list containing some Integer numbers:
```haskell