diff --git a/source_md/higher-order-functions.md b/source_md/higher-order-functions.md index eed0ec2..d19e317 100644 --- a/source_md/higher-order-functions.md +++ b/source_md/higher-order-functions.md @@ -491,7 +491,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. diff --git a/source_md/input-and-output.md b/source_md/input-and-output.md index 7a440d3..4835bc5 100644 --- a/source_md/input-and-output.md +++ b/source_md/input-and-output.md @@ -2311,3 +2311,4 @@ 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 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`. + diff --git a/source_md/making-our-own-types-and-typeclasses.md b/source_md/making-our-own-types-and-typeclasses.md index 504b266..70fde8c 100644 --- a/source_md/making-our-own-types-and-typeclasses.md +++ b/source_md/making-our-own-types-and-typeclasses.md @@ -35,7 +35,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. diff --git a/source_md/recursion.md b/source_md/recursion.md index 21d2bb2..3c7dc8e 100644 --- a/source_md/recursion.md +++ b/source_md/recursion.md @@ -15,13 +15,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!