Skip to content

Commit 58651fd

Browse files
authored
Merge branch 'main' into monoid-update-boring-parts
Signed-off-by: Matthijs <[email protected]>
2 parents 2fe349f + d7833f4 commit 58651fd

10 files changed

Lines changed: 168 additions & 174 deletions

source_md/a-fistful-of-monads.md

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ Wow, who would have thought?
208208
This is what the type class looks like:
209209

210210
```{.haskell:hs}
211-
class Monad m where
211+
class Applicative m => Monad m where
212212
return :: a -> m a
213213
214214
(>>=) :: m a -> (a -> m b) -> m b
@@ -222,13 +222,6 @@ class Monad m where
222222

223223
![this is you on monads](assets/images/a-fistful-of-monads/kid.png){.right width=363 height=451}
224224

225-
Let's start with the first line.
226-
It says `class Monad m where`.
227-
But wait, didn't we say that monads are just beefed up applicative functors?
228-
Shouldn't there be a class constraint in there along the lines of `class (Applicative m) => Monad m where` so that a type has to be an applicative functor first before it can be made a monad?
229-
Well, there should, but when Haskell was made, it hadn't occurred to people that applicative functors are a good fit for Haskell so they weren't in there.
230-
But rest assured, every monad is an applicative functor, even if the `Monad` class declaration doesn't say so.
231-
232225
The first function that the `Monad` type class defines is `return`.
233226
It's the same as `pure`, only with a different name.
234227
Its type is `(Monad m) => a -> m a`.

source_md/for-a-few-monads-more.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,7 @@ Finally, we introduced monads as improved applicative functors, which added the
11751175

11761176
So every monad is an applicative functor and every applicative functor is a functor.
11771177
The `Applicative` type class has a class constraint such that our type has to be an instance of `Functor` before we can make it an instance of `Applicative`.
1178-
But even though `Monad` should have the same constraint for `Applicative`, as every monad is an applicative functor, it doesn't, because the `Monad` type class was introduced to Haskell way before `Applicative`.
1178+
Likewise, the `Monad` class enforces an `Applicative` constraint, ensuring every monad instance is strictly built upon an applicative functor instance.
11791179

11801180
But even though every monad is a functor, we don't have to rely on it having a `Functor` instance because of the `liftM` function.
11811181
`liftM` takes a function and a monadic value and maps it over the monadic value.

source_md/functors-applicative-functors-and-monoids.md

Lines changed: 56 additions & 56 deletions
Large diffs are not rendered by default.

source_md/higher-order-functions.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ From the definition of sections, `(-4)` would result in a function that takes a
130130
However, for convenience, `(-4)` means minus four.
131131
So if you want to make a function that subtracts 4 from the number it gets as a parameter, partially apply the `subtract` function like so: `(subtract 4)`.
132132

133-
What happens if we try to just do `multThree 3 4` in GHCi instead of binding it to a name with a *let* or passing it to another function?
133+
What happens if we try to just do `multThree 3 4` in GHCi instead of binding it to a name with a `let` or passing it to another function?
134134

135135
```{.haskell:hs}
136136
ghci> multThree 3 4
@@ -495,7 +495,7 @@ To make a lambda, we write a `\` (because it kind of looks like the greek letter
495495
After that comes a `->` and then the function body.
496496
We usually surround them by parentheses, because otherwise they extend all the way to the right.
497497

498-
If you look about 5 inches up, you'll see that we used a *where* binding in our `numLongChains` function to make the `isLong` function for the sole purpose of passing it to `filter`.
498+
If you look about 5 inches up, you'll see that we used a `where` binding in our `numLongChains` function to make the `isLong` function for the sole purpose of passing it to `filter`.
499499
Well, instead of doing that, we can use a lambda:
500500

501501
```{.haskell:hs}
@@ -960,7 +960,7 @@ Many times, a point free style is more readable and concise, because it makes yo
960960
You can take simple functions and use composition as glue to form more complex functions.
961961
However, many times, writing a function in point free style can be less readable if a function is too complex.
962962
That's why making long chains of function composition is discouraged, although I plead guilty of sometimes being too composition-happy.
963-
The preferred style is to use *let* bindings to give labels to intermediary results or split the problem into sub-problems and then put it together so that the function makes sense to someone reading it instead of just making a huge composition chain.
963+
The preferred style is to use `let` bindings to give labels to intermediary results or split the problem into sub-problems and then put it together so that the function makes sense to someone reading it instead of just making a huge composition chain.
964964

965965
In the section about maps and filters, we solved a problem of finding the sum of all odd squares that are smaller than 10,000.
966966
Here's what the solution looks like when put into a function.

0 commit comments

Comments
 (0)