Skip to content

Commit 1f5e18d

Browse files
authored
[Chapter 5] Use pattern matching (ch4) in ch5 (#465)
* chore: use pattern matching (ch4) in ch5 * Remove leftover if/then/else
1 parent c584cf0 commit 1f5e18d

File tree

2 files changed

+13
-33
lines changed

2 files changed

+13
-33
lines changed

exercises/chapter5/test/Examples.purs

+11-25
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,21 @@ import Data.Path (Path, ls)
99

1010
-- ANCHOR: factorial
1111
factorial :: Int -> Int
12-
factorial n =
13-
if n == 0 then
14-
1
15-
else
16-
n * factorial (n - 1)
12+
factorial 0 = 1
13+
factorial n = n * factorial (n - 1)
1714
-- ANCHOR_END: factorial
1815

1916
-- ANCHOR: fib
2017
fib :: Int -> Int
21-
fib n =
22-
if n == 0 then
23-
0
24-
else if n == 1 then
25-
1
26-
else
27-
fib (n - 1) + fib (n - 2)
18+
fib 0 = 0
19+
fib 1 = 1
20+
fib n = fib (n - 1) + fib (n - 2)
2821
-- ANCHOR_END: fib
2922

3023
-- ANCHOR: length
3124
length :: forall a. Array a -> Int
32-
length arr =
33-
if null arr then
34-
0
35-
else
36-
1 + (length $ fromMaybe [] $ tail arr)
25+
length [] = 0
26+
length arr = 1 + (length $ fromMaybe [] $ tail arr)
3727
-- ANCHOR_END: length
3828

3929
-- ANCHOR: factors
@@ -63,21 +53,17 @@ factorsV3 n = do
6353

6454
-- ANCHOR: factorialTailRec
6555
factorialTailRec :: Int -> Int -> Int
66-
factorialTailRec n acc =
67-
if n == 0
68-
then acc
69-
else factorialTailRec (n - 1) (acc * n)
56+
factorialTailRec 0 acc = acc
57+
factorialTailRec n acc = factorialTailRec (n - 1) (acc * n)
7058
-- ANCHOR_END: factorialTailRec
7159

7260
-- ANCHOR: lengthTailRec
7361
lengthTailRec :: forall a. Array a -> Int
7462
lengthTailRec arr = length' arr 0
7563
where
7664
length' :: Array a -> Int -> Int
77-
length' arr' acc =
78-
if null arr'
79-
then acc
80-
else length' (fromMaybe [] $ tail arr') (acc + 1)
65+
length' [] acc = acc
66+
length' arr' acc = length' (fromMaybe [] $ tail arr') (acc + 1)
8167
-- ANCHOR_END: lengthTailRec
8268

8369
-- ANCHOR: allFiles_signature

text/chapter5.md

+2-8
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ Here is another common example that computes the _Fibonacci function_:
4646

4747
Again, this problem is solved by considering the solutions to subproblems. In this case, there are two subproblems, corresponding to the expressions `fib (n - 1)` and `fib (n - 2)`. When these two subproblems are solved, we assemble the result by adding the partial results.
4848

49-
> Note that, while the above examples of `factorial` and `fib` work as intended, a more idiomatic implementation would use pattern matching instead of `if`/`then`/`else`. Pattern-matching techniques are discussed in a later chapter.
50-
5149
## Recursion on Arrays
5250

5351
We are not limited to defining recursive functions over the `Int` type! We will see recursive functions defined over a wide array of data types when we cover _pattern matching_ later in the book, but for now, we will restrict ourselves to numbers and arrays.
@@ -63,7 +61,7 @@ import Data.Maybe (fromMaybe)
6361
{{#include ../exercises/chapter5/test/Examples.purs:length}}
6462
```
6563

66-
In this function, we use an `if .. then .. else` expression to branch based on the emptiness of the array. The `null` function returns `true` on an empty array. Empty arrays have a length of zero, and a non-empty array has a length that is one more than the length of its tail.
64+
In this function, we branch based on the emptiness of the array. The `null` function returns `true` on an empty array. Empty arrays have a length of zero, and a non-empty array has a length that is one more than the length of its tail.
6765

6866
The `tail` function returns a `Maybe` wrapping the given array without its first element. If the array is empty (i.e., it doesn't have a tail), `Nothing` is returned. The `fromMaybe` function takes a default value and a `Maybe` value. If the latter is `Nothing` it returns the default; in the other case, it returns the value wrapped by `Just`.
6967

@@ -489,11 +487,7 @@ One common way to turn a not tail recursive function into a tail recursive is to
489487
For example, consider again the `length` function presented at the beginning of the chapter:
490488

491489
```haskell
492-
length :: forall a. Array a -> Int
493-
length arr =
494-
if null arr
495-
then 0
496-
else 1 + (length $ fromMaybe [] $ tail arr)
490+
{{#include ../exercises/chapter5/test/Examples.purs:length}}
497491
```
498492

499493
This implementation is not tail recursive, so the generated JavaScript will cause a stack overflow when executed on a large input array. However, we can make it tail recursive, by introducing a second function argument to accumulate the result instead:

0 commit comments

Comments
 (0)