Skip to content

Commit a6da585

Browse files
authored
Various bug fixes and clarifications in Approaches (#1175)
* Various bug fixes and clarifications * Update content.md
1 parent c587770 commit a6da585

File tree

7 files changed

+31
-22
lines changed

7 files changed

+31
-22
lines changed

exercises/practice/bob/.approaches/string/content.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,28 @@ How do these work?
5858

5959
~~~~exercism/advanced
6060
To find they actual definitions of `any` and `all`, look up their documentation (for example through [Hoogle][hoogle]) and click on the «Source» link next to the type signature.
61+
6162
The definitions of `any` and `all` look kinda complicated!
6263
They are this way so that they can also be used on types other than lists, such as `Set`, `Map`, and `Tree`.
6364
Specifically, they can be used on any type that is an instance of the `Foldable` type class.
65+
6466
In the source code, you can click on names to jump to their definitions.
6567
This doesn't really work for `foldMap` here though: it sends you to its default (general) implementation, but here we need its implementation for lists specifically.
6668
To find that code, navigate to the documentation of `Foldable`, look up `[]` in the list of «Instances», and click «Source».
69+
6770
It might be hard to see – even after lots of clicking through to definitions – but these definitions of `any` and `all` work essentially the same way as the one outlined here below.
68-
[hoogle]: https://hoogle.haskell.org/ "Hoogle"
71+
72+
[hoogle]:
73+
https://hoogle.haskell.org/
74+
"Hoogle"
6975
~~~~
7076

7177
Here is a possible definition of `any`:
7278

7379
```haskell
7480
or :: [Bool] -> Bool
7581
or = foldr (||) True
82+
7683
any p = or . map p
7784
```
7885

exercises/practice/bob/.approaches/text/content.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ dependencies:
3333
Thereafter you can import functions as you would normally:
3434
3535
```haskell
36-
-- these names can be used by themselves
36+
-- allow using the following names by themselves
3737
import Data.Text (Text, strip, unsnoc)
3838

39-
-- all other names from `Data.Text` need to be prefixed with `Text.`
39+
-- require all other names from `Data.Text` to be prefixed with `Text.`
4040
import qualified Data.Text as Text
4141
```
4242

@@ -131,8 +131,8 @@ minimum unsorted =
131131

132132
This is a bit more verbose.
133133
But more importantly it introduces an extra name: `unsorted`.
134-
We intend to use only once (to `sort` it), but we might use it in more places by accident.
134+
We intend to use it only once (to `sort` it), but we might accidentally use it in more places.
135135
By eliminating the need for an extra name, the view pattern makes it impossible to make this mistake.
136136

137137
The solution highlighted above uses a view pattern to remove initial and trailing spaces from the input.
138-
That way, `isSilent` and `isQuestion` need not do it themselves anymore, or the introduction of an otherwise unnecessary name is avoided.
138+
That way, `isSilent` and `isQuestion` need not do it themselves anymore, or the introduction of an otherwise unnecessary name (for the stripped query) is avoided.

exercises/practice/collatz-conjecture/.approaches/list-of-steps/content.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ This is the only logic that is provided by us instead of by the standard library
8989
The sequence of steps should be terminated at the first `1`.
9090
`unfoldr` does this by itself, but `iterate` needs some help from `takeWhile`.
9191

92-
With a complete sequence of steps, the only thing that remains to be done is count them.
92+
With a complete sequence of steps, the only thing that remains to be done is to count them.
9393
We simply use `length` for this.
9494

9595
Haskell's laziness helps this approach be efficient.

exercises/practice/collatz-conjecture/.approaches/recursion/content.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ Instead, all 'loopiness' in Haskell is produced through recursion – if not
7474
## In this approach
7575

7676
First, we compare the input with `1`.
77-
If it is less than `1` the input is invalid and we return `Nothing`.
77+
If it is less than `1` then the input is invalid and we return `Nothing`.
7878
If it is exactly `1`, then the number of steps it takes to reach `1` is zero – because we're already there – so we return `Just 0`.
7979

8080
If the input is greater than `1`, it'll take at least one step to get to `1`.

exercises/practice/collatz-conjecture/.approaches/worker-wrapper/content.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ However, variables do not exist in Haskell: all bindings are constants.
2222

2323
In lieu of local variables we can add extra parameters to our functions.
2424
These will hold our state.
25-
'Changing' of the state is done by calling the same functions with different arguments.
25+
'Changing' the state is done by calling the same functions (recursively) with different arguments.
2626

27-
Functions that uses such additional parameters to represent state are often called _workers_, and functions that use them are often called _wrappers_.
27+
Functions that uses such additional parameters to represent state are often called _workers_, and functions that use workers to solve a problem in a stateful way are often called _wrappers_.
2828

2929
As an example, consider the following possible definition of `length`.
3030

@@ -98,7 +98,7 @@ For a few more more examples, see the [relevant wiki article][wiki-worker-wrappe
9898
## Bang patterns
9999

100100
The above implementation of `length'` _might_ evaluate as efficiently as illustrated.
101-
However, it also might not!
101+
However, depending on which optimization opportunities are spotted by the compiler, it also might not!
102102
The definition of `length'` allows evaluation to proceed as follows as well.
103103

104104
```haskell
@@ -122,11 +122,12 @@ The situation is not quite as bad as before though.
122122
In the case of the naive implementation of `length`, the built up expression has the form
123123

124124
```haskell
125-
_ = 1 + (1 + ((1 + length xs)))
125+
_ = 1 + (1 + ((1 + length )))
126126
```
127127

128-
This expression cannot be simplified before `length xs` has been evaluated.
129-
As a consequence, it must grow as big as the original list.
128+
This expression cannot be simplified before `length …` has been evaluated.
129+
That is, simplification cannot begin until the last recursive step has been evaluated.
130+
As a consequence, the computation must grow as big as the original list.
130131

131132
The computation built up by `length'` on the other hand has the form
132133

@@ -141,7 +142,7 @@ Haskell offers various ways to force intermediate evaluation.
141142
One convenient tool is the _bang pattern_, enabled by the `BangPatterns` language extension.
142143

143144
```haskell
144-
{-# LANGUAGE BangPatterns #-} -- at the top of the file
145+
{-# LANGUAGE BangPatterns #-} -- 👈 at the top of the file
145146

146147
length'' :: Int -> [a] -> Int
147148
length'' !count [] = count

exercises/practice/hamming/.approaches/introduction.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ You can use `fmap`/`<$>` for this.
5050
[Read more about this approach][recursion]
5151

5252

53-
## Approach: a worker&wrapper construct
53+
## Approach: a worker&ndash;wrapper construct
5454

5555
```haskell
5656
distance :: String -> String -> Maybe Int

exercises/practice/hamming/.approaches/worker-wrapper/content.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ However, variables do not exist in Haskell: all bindings are constants.
2121

2222
In lieu of local variables we can add extra parameters to our functions.
2323
These will hold our state.
24-
'Changing' of the state is done by calling the same functions with different arguments.
24+
'Changing' the state is done by calling the same functions (recursively) with different arguments.
2525

26-
Functions that uses such additional parameters to represent state are often called _workers_, and functions that use them are often called _wrappers_.
26+
Functions that uses such additional parameters to represent state are often called _workers_, and functions that use workers to solve a problem in a stateful way are often called _wrappers_.
2727

2828
As an example, consider the following possible definition of `length`.
2929

@@ -97,7 +97,7 @@ For a few more more examples, see the [relevant wiki article][wiki-worker-wrappe
9797
## Bang patterns
9898

9999
The above implementation of `length'` _might_ evaluate as efficiently as illustrated.
100-
However, it also might not!
100+
However, depending on which optimization opportunities are spotted by the compiler, it also might not!
101101
The definition of `length'` allows evaluation to proceed as follows as well.
102102

103103
```haskell
@@ -121,11 +121,12 @@ The situation is not quite as bad as before though.
121121
In the case of the naive implementation of `length`, the built up expression has the form
122122

123123
```haskell
124-
_ = 1 + (1 + ((1 + length xs)))
124+
_ = 1 + (1 + ((1 + length )))
125125
```
126126

127-
This expression cannot be simplified before `length xs` has been evaluated.
128-
As a consequence, it must grow as big as the original list.
127+
This expression cannot be simplified before `length …` has been evaluated.
128+
That is, simplification cannot begin until the last recursive step has been evaluated.
129+
As a consequence, the computation must grow as big as the original list.
129130

130131
The computation built up by `length'` on the other hand has the form
131132

@@ -140,7 +141,7 @@ Haskell offers various ways to force intermediate evaluation.
140141
One convenient tool is the _bang pattern_, enabled by the `BangPatterns` language extension.
141142

142143
```haskell
143-
{-# LANGUAGE BangPatterns #-} -- at the top of the file
144+
{-# LANGUAGE BangPatterns #-} -- 👈 at the top of the file
144145

145146
length'' :: Int -> [a] -> Int
146147
length'' !count [] = count

0 commit comments

Comments
 (0)