From ef2ef24001633df4e9ae7adcf3b5d1cb6eee99ff Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 19:41:16 +0000 Subject: [PATCH 01/16] 'auxilliary' > 'auxiliary' --- markdown/source_md/zippers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/zippers.md b/markdown/source_md/zippers.md index 83148a66..b7b6f062 100644 --- a/markdown/source_md/zippers.md +++ b/markdown/source_md/zippers.md @@ -544,7 +544,7 @@ First we use `break` to break the list of items in a folder into those that prec If you remember, `break` takes a predicate and a list and returns a pair of lists. The first list in the pair holds items for which the predicate returns `False`. Then, once the predicate returns `True` for an item, it places that item and the rest of the list in the second item of the pair. -We made an auxilliary function called `nameIs` that takes a name and a file system item and returns `True` if the names match. +We made an auxiliary function called `nameIs` that takes a name and a file system item and returns `True` if the names match. So now, `ls` is a list that contains the items that precede the item that we're searching for, `item` is that very item and `rs` is the list of items that come after it in its folder. Now that we have this, we just present the item that we got from `break` as the focus and build a breadcrumb that has all the data it needs. From 7cac746f79c74c84e9ae09c2c6e7361fa0922192 Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 19:46:19 +0000 Subject: [PATCH 02/16] 'hypothenuse' > 'hypotenuse' --- markdown/source_md/starting-out.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/starting-out.md b/markdown/source_md/starting-out.md index c30c892e..7755660c 100644 --- a/markdown/source_md/starting-out.md +++ b/markdown/source_md/starting-out.md @@ -881,7 +881,7 @@ ghci> triangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10] ] We're just drawing from three lists and our output function is combining them into a triple. If you evaluate that by typing out `triangles` in GHCI, you'll get a list of all possible triangles with sides under or equal to 10. Next, we'll add a condition that they all have to be right triangles. -We'll also modify this function by taking into consideration that side b isn't larger than the hypothenuse and that side a isn't larger than side b. +We'll also modify this function by taking into consideration that side b isn't larger than the hypotenuse and that side a isn't larger than side b. ```{.haskell: .ghci} ghci> rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2] From 64bcee749d06e04505820d74d49f081458ff68f2 Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 19:53:20 +0000 Subject: [PATCH 03/16] 'fibonacci' > 'Fibonacci' --- markdown/source_md/recursion.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/markdown/source_md/recursion.md b/markdown/source_md/recursion.md index 7057f6dc..33fd8321 100644 --- a/markdown/source_md/recursion.md +++ b/markdown/source_md/recursion.md @@ -12,13 +12,13 @@ Haha! Just kidding! Recursion is actually a way of defining functions in which the function is applied inside its own definition. Definitions in mathematics are often given recursively. -For instance, the fibonacci sequence is defined recursively. -First, we define the first two fibonacci numbers non-recursively. -We say that *F(0) = 0* and *F(1) = 1*, meaning that the 0th and 1st fibonacci numbers are 0 and 1, respectively. -Then we say that for any other natural number, that fibonacci number is the sum of the previous two fibonacci numbers. +For instance, the Fibonacci sequence is defined recursively. +First, we define the first two Fibonacci numbers non-recursively. +We say that *F(0) = 0* and *F(1) = 1*, meaning that the 0th and 1st Fibonacci numbers are 0 and 1, respectively. +Then we say that for any other natural number, that Fibonacci number is the sum of the previous two Fibonacci numbers. So *F(n) = F(n-1) + F(n-2)*. That way, *F(3)* is *F(2) + F(1)*, which is *(F(1) + F(0)) + F(1)*. -Because we've now come down to only non-recursively defined fibonacci numbers, we can safely say that *F(3)* is 2. +Because we've now come down to only non-recursively defined Fibonacci numbers, we can safely say that *F(3)* is 2. Having an element or two in a recursion definition defined non-recursively (like *F(0)* and *F(1)* here) is also called the **edge condition** and is important if you want your recursive function to terminate. If we hadn't defined *F(0)* and *F(1)* non recursively, you'd never get a solution any number because you'd reach 0 and then you'd go into negative numbers. All of a sudden, you'd be saying that *F(-2000)* is *F(-2001) + F(-2002)* and there still wouldn't be an end in sight! From c704fc90ba006a0aa077137f4478b29da0edece2 Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 19:56:05 +0000 Subject: [PATCH 04/16] 'ekcetera' > 'et cetera' --- markdown/source_md/recursion.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/recursion.md b/markdown/source_md/recursion.md index 33fd8321..72c1b8b8 100644 --- a/markdown/source_md/recursion.md +++ b/markdown/source_md/recursion.md @@ -296,7 +296,7 @@ It doesn't matter if it's a list, a tree or any other data structure. A sum is the first element of a list plus the sum of the rest of the list. A product of a list is the first element of the list times the product of the rest of the list. The length of a list is one plus the length of the tail of the list. -Ekcetera, ekcetera ... +Et cetera, et cetera ... ![brain](assets/images/recursion/brain.png){.left width=250 height=219} From f5c848cf24ed7caf76ba9efc51bedfc806e30555 Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 19:58:29 +0000 Subject: [PATCH 05/16] 'lenghts' > 'lengths' --- markdown/source_md/modules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/modules.md b/markdown/source_md/modules.md index afe40b95..26a91038 100644 --- a/markdown/source_md/modules.md +++ b/markdown/source_md/modules.md @@ -1328,7 +1328,7 @@ rectangleArea a b = a * b Pretty standard geometry right here. There are a few things to take note of though. Because a cube is only a special case of a cuboid, we defined its area and volume by treating it as a cuboid whose sides are all of the same length. -We also defined a helper function called `rectangleArea`, which calculates a rectangle's area based on the lenghts of its sides. +We also defined a helper function called `rectangleArea`, which calculates a rectangle's area based on the lengths of its sides. It's rather trivial because it's just multiplication. Notice that we used it in our functions in the module (namely `cuboidArea` and `cuboidVolume`) but we didn't export it! Because we want our module to just present functions for dealing with three-dimensional objects, we used `rectangleArea` but we didn't export it. From 02d6c6da08ec5991c9763fb726b4cb3faf6643f0 Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 20:01:00 +0000 Subject: [PATCH 06/16] 'heapload' > 'heap load' --- markdown/source_md/making-our-own-types-and-typeclasses.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/making-our-own-types-and-typeclasses.md b/markdown/source_md/making-our-own-types-and-typeclasses.md index b24960b3..5e952c44 100644 --- a/markdown/source_md/making-our-own-types-and-typeclasses.md +++ b/markdown/source_md/making-our-own-types-and-typeclasses.md @@ -32,7 +32,7 @@ data Int = -2147483648 | -2147483647 | ... | -1 | 0 | 1 | 2 | ... | 2147483647 ![caveman](assets/images/making-our-own-types-and-typeclasses/caveman.png){.left width=220 height=215} The first and last value constructors are the minimum and maximum possible values of `Int`. -It's not actually defined like this, the ellipses are here because we omitted a heapload of numbers, so this is just for illustrative purposes. +It's not actually defined like this, the ellipses are here because we omitted a heap load of numbers, so this is just for illustrative purposes. Now, let's think about how we would represent a shape in Haskell. One way would be to use tuples. From 2bad30e84e5c3b7e624bc043845e28a2c72fc3c7 Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 20:05:17 +0000 Subject: [PATCH 07/16] 'glueing' > 'gluing' --- markdown/source_md/input-and-output.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/input-and-output.md b/markdown/source_md/input-and-output.md index 6a9b066c..9c07aa1d 100644 --- a/markdown/source_md/input-and-output.md +++ b/markdown/source_md/input-and-output.md @@ -2306,4 +2306,4 @@ This is kind of similar to *try-catch* blocks of other languages, where you can Now you know how to deal with I/O exceptions! Throwing exceptions from pure code and dealing with them hasn't been covered here, mainly because, like we said, Haskell offers much better ways to indicate errors than reverting to I/O to catch them. -Even when glueing together I/O actions that might fail, I prefer to have their type be something like `IO (Either a b)`, meaning that they're normal I/O actions but the result that they yield when performed is of type `Either a b`, meaning it's either `Left a` or `Right b`. +Even when gluing together I/O actions that might fail, I prefer to have their type be something like `IO (Either a b)`, meaning that they're normal I/O actions but the result that they yield when performed is of type `Either a b`, meaning it's either `Left a` or `Right b`. From 38c1388a57098e9af0aabc9fca35887237e6681f Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 20:06:46 +0000 Subject: [PATCH 08/16] 'greek' > 'Greek' --- markdown/source_md/higher-order-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/higher-order-functions.md b/markdown/source_md/higher-order-functions.md index d3bcef86..5c96f1e3 100644 --- a/markdown/source_md/higher-order-functions.md +++ b/markdown/source_md/higher-order-functions.md @@ -488,7 +488,7 @@ So that's like writing `(4*) 5` or just `4 * 5`. Lambdas are basically anonymous functions that are used because we need some functions only once. Normally, we make a lambda with the sole purpose of passing it to a higher-order function. -To make a lambda, we write a `\` (because it kind of looks like the greek letter lambda if you squint hard enough) and then we write the parameters, separated by spaces. +To make a lambda, we write a `\` (because it kind of looks like the Greek letter lambda if you squint hard enough) and then we write the parameters, separated by spaces. After that comes a `->` and then the function body. We usually surround them by parentheses, because otherwise they extend all the way to the right. From e68112a5ca64b06270c0baeeb397f017be7e6ebb Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 20:08:06 +0000 Subject: [PATCH 09/16] 'adjecent' > 'adjacent' --- markdown/source_md/functors-applicative-functors-and-monoids.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/functors-applicative-functors-and-monoids.md b/markdown/source_md/functors-applicative-functors-and-monoids.md index d93c1754..13972bb5 100644 --- a/markdown/source_md/functors-applicative-functors-and-monoids.md +++ b/markdown/source_md/functors-applicative-functors-and-monoids.md @@ -1578,7 +1578,7 @@ We were able to use the general type of `[a]` (as opposed to specifying `[Int]` Because `mconcat` has a default implementation, we get it for free when we make something an instance of `Monoid`. In the case of the list, `mconcat` turns out to be just `concat`. -It takes a list of lists and flattens it, because that's the equivalent of doing `++` between all the adjecent lists in a list. +It takes a list of lists and flattens it, because that's the equivalent of doing `++` between all the adjacent lists in a list. The monoid laws do indeed hold for the list instance. When we have several lists and we `mappend` (or `++`) them together, it doesn't matter which ones we do first, because they're just joined at the ends anyway. From cb2c5e133c10fa9d354ff03ec61680409effb1cc Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 20:08:31 +0000 Subject: [PATCH 10/16] 'occurences' > 'occurrences' --- markdown/source_md/functors-applicative-functors-and-monoids.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/functors-applicative-functors-and-monoids.md b/markdown/source_md/functors-applicative-functors-and-monoids.md index 13972bb5..e876929e 100644 --- a/markdown/source_md/functors-applicative-functors-and-monoids.md +++ b/markdown/source_md/functors-applicative-functors-and-monoids.md @@ -586,7 +586,7 @@ Finally, `Just (3+) <*> Just 5` is carried out, which results in a `Just 8`. Isn't this awesome?! Applicative functors and the applicative style of doing `pure f <*> x <*> y <*> ...` allow us to take a function that expects parameters that aren't necessarily wrapped in functors and use that function to operate on several values that are in functor contexts. -The function can take as many parameters as we want, because it's always partially applied step by step between occurences of `<*>`. +The function can take as many parameters as we want, because it's always partially applied step by step between occurrences of `<*>`. This becomes even more handy and apparent if we consider the fact that `pure f <*> x` equals `fmap f x`. This is one of the applicative laws. From 99a1621e37bb0f149c22d3ad14ee92fd68da721f Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 20:11:03 +0000 Subject: [PATCH 11/16] 'intial' > 'initial' --- markdown/source_md/functionally-solving-problems.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/functionally-solving-problems.md b/markdown/source_md/functionally-solving-problems.md index e109e247..55c107e2 100644 --- a/markdown/source_md/functionally-solving-problems.md +++ b/markdown/source_md/functionally-solving-problems.md @@ -138,7 +138,7 @@ Also noticed that we added an extra class constraint of `Read a` to the function So this declaration means that the result can be of any type that's part of the `Num` and `Read` typeclasses (like `Int`, `Float`, etc.). For the list of items `["2","3","+"]`, our function will start folding from the left. -The intial stack will be `[]`. +The initial stack will be `[]`. It will call the folding function with `[]` as the stack (accumulator) and `"2"` as the item. Because that item is not an operator, it will be `read` and the added to the beginning of `[]`. So the new stack is now `[2]` and the folding function will be called with `[2]` as the stack and `["3"]` as the item, producing a new stack of `[3,2]`. From 2cbe1d2e87e27d243907b773918f150decdbda95 Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 20:12:47 +0000 Subject: [PATCH 12/16] 'let'use' > 'lets' --- markdown/source_md/for-a-few-monads-more.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/for-a-few-monads-more.md b/markdown/source_md/for-a-few-monads-more.md index 0fb17c47..e8812843 100644 --- a/markdown/source_md/for-a-few-monads-more.md +++ b/markdown/source_md/for-a-few-monads-more.md @@ -1823,7 +1823,7 @@ ghci> 1%3 + 5%4 The first line is just one quarter. In the second line we add two halves to get a whole and in the third line we add one third with five quarters and get nineteen twelfths. -So let'use throw out our floating points and use `Rational` for our probabilities: +So lets throw out our floating points and use `Rational` for our probabilities: ```{.haskell:hs} ghci> [(3,1%2),(5,1%4),(9,1%4)] From fcde592d73e8d9bfa837ddfde556566120c20948 Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 20:15:41 +0000 Subject: [PATCH 13/16] =?UTF-8?q?'voila'=20>=20'voil=C3=A0'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- markdown/source_md/a-fistful-of-monads.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/a-fistful-of-monads.md b/markdown/source_md/a-fistful-of-monads.md index 9eaf959c..ac340292 100644 --- a/markdown/source_md/a-fistful-of-monads.md +++ b/markdown/source_md/a-fistful-of-monads.md @@ -879,7 +879,7 @@ Then, we map the lambda over it and the result is the following: ``` The lambda is applied to every element and we get a list of lists. -Finally, we just flatten the list and voila! +Finally, we just flatten the list and voilĂ ! We've applied a non-deterministic function to a non-deterministic value! Non-determinism also includes support for failure. From 48a28c8d0a60a5bea55b53b35eb97f29e564312b Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Tue, 6 Jan 2026 20:17:18 +0000 Subject: [PATCH 14/16] 'tightwalker' > 'tightrope walker' --- markdown/source_md/a-fistful-of-monads.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/markdown/source_md/a-fistful-of-monads.md b/markdown/source_md/a-fistful-of-monads.md index ac340292..77f23bf2 100644 --- a/markdown/source_md/a-fistful-of-monads.md +++ b/markdown/source_md/a-fistful-of-monads.md @@ -694,8 +694,8 @@ marySue = do If we compare these two, it's easy to see why the result of the whole monadic value is the result of the last monadic value in the `do` expression with all the previous ones chained into it. -Our tightwalker's routine can also be expressed with `do` notation. -`landLeft` and `landRight` take a number of birds and a pole and produce a pole wrapped in a `Just`, unless the tightwalker slips, in which case a `Nothing` is produced. +Our tightrope walker's routine can also be expressed with `do` notation. +`landLeft` and `landRight` take a number of birds and a pole and produce a pole wrapped in a `Just`, unless the tightrope walker slips, in which case a `Nothing` is produced. We used `>>=` to chain successive steps because each one relied on the previous one and each one had an added context of possible failure. Here's two birds landing on the left side, then two birds landing on the right and then one bird landing on the left: From f2586aa9caae47cc50f89ecd818675e3b94872a6 Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Wed, 7 Jan 2026 18:27:55 +0000 Subject: [PATCH 15/16] Revert "'let'use' > 'lets'" This reverts commit 2cbe1d2e87e27d243907b773918f150decdbda95. --- markdown/source_md/for-a-few-monads-more.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/for-a-few-monads-more.md b/markdown/source_md/for-a-few-monads-more.md index e8812843..0fb17c47 100644 --- a/markdown/source_md/for-a-few-monads-more.md +++ b/markdown/source_md/for-a-few-monads-more.md @@ -1823,7 +1823,7 @@ ghci> 1%3 + 5%4 The first line is just one quarter. In the second line we add two halves to get a whole and in the third line we add one third with five quarters and get nineteen twelfths. -So lets throw out our floating points and use `Rational` for our probabilities: +So let'use throw out our floating points and use `Rational` for our probabilities: ```{.haskell:hs} ghci> [(3,1%2),(5,1%4),(9,1%4)] From bfa8706f3a89c2906d74c72d3e9fdcb3e58ccb69 Mon Sep 17 00:00:00 2001 From: Chris Denman Date: Wed, 7 Jan 2026 18:28:32 +0000 Subject: [PATCH 16/16] 'let'use' > 'let's' --- markdown/source_md/for-a-few-monads-more.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/source_md/for-a-few-monads-more.md b/markdown/source_md/for-a-few-monads-more.md index 0fb17c47..10d6c60d 100644 --- a/markdown/source_md/for-a-few-monads-more.md +++ b/markdown/source_md/for-a-few-monads-more.md @@ -1823,7 +1823,7 @@ ghci> 1%3 + 5%4 The first line is just one quarter. In the second line we add two halves to get a whole and in the third line we add one third with five quarters and get nineteen twelfths. -So let'use throw out our floating points and use `Rational` for our probabilities: +So let's throw out our floating points and use `Rational` for our probabilities: ```{.haskell:hs} ghci> [(3,1%2),(5,1%4),(9,1%4)]