Skip to content

Commit 262dd20

Browse files
Xingye-Dujingulysses4ever
authored andcommitted
Adjust details
1 parent 58b7b23 commit 262dd20

1 file changed

Lines changed: 13 additions & 13 deletions

File tree

source_md/higher-order-functions.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ It would be `map' f xs = foldl (\acc x -> acc ++ [f x]) [] xs`, but the thing is
673673
If you reverse a list, you can do a right fold on it just like you would have done a left fold and vice versa.
674674
Sometimes you don't even have to do that.
675675
The `sum` function can be implemented pretty much the same with a left and right fold.
676-
**One big difference is that right folds work on infinite lists, whereas left ones don't!**
676+
One big difference is that right folds work on infinite lists, whereas left ones don't!
677677

678678
**Folds can be used to implement any function where you traverse a list once, element by element, and then return something based on that.
679679
Whenever you want to traverse a list to return something, chances are you want a fold.**
@@ -697,12 +697,12 @@ containsThree = foldr (\x rest -> if x == 3 then True else rest) False
697697

698698
Let's unfold this step-by-step on the infinite list `[1,2,3,4,...]`:
699699

700-
1. Start: `foldr (...) False [1,2,3,4,...]`
701-
2. For `x = 1`: `if 1 == 3 then True else (foldr (...) False [2,3,4,...])` $\to$ `1 /= 3`, so this becomes `foldr (...) False [2,3,4,...]` (we recurse).
702-
3. For `x = 2`: `if 2 == 3 then True else (foldr (...) False [3,4,5,...])` $\to$ `2 /= 3`, so this becomes `foldr (...) False [3,4,5,...]` (we recurse again).
703-
4. For `x = 3`: `if 3 == 3 then True else (foldr (...) False [4,5,6,...])` $\to$ `3 == 3` is `True`! **Here, `f` ignores the recursive call (the `[4,5,6,...]` part) and returns `True` immediately**.
700+
- Start: `foldr (...) False [1,2,3,4,...]`
701+
- For `x = 1`: `if 1 == 3 then True else (foldr (...) False [2,3,4,...])`. Since `1 == 3` is `False`, the expression becomes `foldr (...) False [2,3,4,...]` (we recurse).
702+
- For `x = 2`: `if 2 == 3 then True else (foldr (...) False [3,4,5,...])`. Since `2 == 3` is `False`, the expression becomes `foldr (...) False [3,4,5,...]` (we recurse again).
703+
- For `x = 3`: `if 3 == 3 then True else (foldr (...) False [4,5,6,...])`. Since `3 == 3` is `True`, **`f` ignores the recursive call (the `[4,5,6,...]` part) and returns `True` immediately**.
704704

705-
<br>Now, contrast this with `foldl`'s definition:
705+
Now, contrast this with `foldl`'s definition:
706706

707707
```{.haskell:hs}
708708
foldl f acc [] = acc
@@ -720,14 +720,14 @@ containsThreeFoldl = foldl (\acc x -> if x == 3 then True else acc) False
720720

721721
Unfolding on `[1,2,3,4,...]`:
722722

723-
1. Start: `acc = False`, list `[1,2,3,4,...]`.
724-
3. Compute `f False 1` $\to$ `if 1==3 then True else False` $\to$ `False`. Recurse: `foldl (...) False [2,3,4,...]`.
725-
4. Compute `f False 2` $\to$ `False`. Recurse: `foldl (...) False [3,4,5,...]`.
726-
5. Compute `f False 3` $\to$ `True`. But now we must recurse: `foldl (...) True [4,5,6,...]`.
727-
6. Compute `f True 4` $\to$ `True` (since `4 /= 3`, it returns the accumulator `True`). But we recurse again: `foldl (...) True [5,6,7,...]`.
728-
7. This continues forever. Even though we found `3`, we never stop.
723+
- Start: `acc = False`, list `[1,2,3,4,...]`.
724+
- Compute `f False 1`, which evaluates to `if 1 == 3 then True else False`, resulting in `False`. Recurse: `foldl (...) False [2,3,4,...]`.
725+
- Compute `f False 2`, which results in `False`. Recurse: `foldl (...) False [3,4,5,...]`.
726+
- Compute `f False 3`, which results in `True`. But now we must recurse: `foldl (...) True [4,5,6,...]`.
727+
- Compute `f True 4`, which results in `True` (since `4 == 3` is `False`, it returns the accumulator `True`). But we recurse again: `foldl (...) True [5,6,7,...]`.
728+
- This continues forever. Even though we found `3`, we never stop.
729729

730-
<br>The `foldr` function can terminate on infinite lists if the function `f` is lazy in its right argument (i.e., `f` can short-circuit by ignoring the recursive result).
730+
The `foldr` function can terminate on infinite lists if the function `f` is lazy in its right argument (i.e., `f` can short-circuit by ignoring the recursive result).
731731
The `foldl` function always processes the list from left to right and cannot short-circuit in the same way, so it fails on infinite lists.
732732
This is why `foldr` is often more suitable for working with infinite lists. Just remember: **the function `f` must be lazy in its right argument for `foldr` to terminate early**.
733733

0 commit comments

Comments
 (0)