diff --git a/src/pages/applicatives/parallel.md b/src/pages/applicatives/parallel.md index 8089891f..6949b9b1 100644 --- a/src/pages/applicatives/parallel.md +++ b/src/pages/applicatives/parallel.md @@ -133,7 +133,7 @@ any values contained with the type constructor `M`. The conversion must be performed purely in terms of the structure of the type constructors `M` and `F`. We can in `optionToList` above -this is indeed the case. +see this is indeed the case. So in summary, `Parallel` allows us to take a type that has a monad instance @@ -155,7 +155,7 @@ Does `List` have a `Parallel` instance? If so, what does the `Parallel` instance
`List` does have a `Parallel` instance, and it zips the `List` -insted of creating the cartesian product. +instead of creating the cartesian product. We can see by writing a little bit of code. diff --git a/src/pages/applicatives/semigroupal.md b/src/pages/applicatives/semigroupal.md index 09bba7d1..426ea57b 100644 --- a/src/pages/applicatives/semigroupal.md +++ b/src/pages/applicatives/semigroupal.md @@ -21,7 +21,6 @@ This gives us more freedom when defining instances of `Semigroupal` than we get when defining `Monads`. [^semigroupal-name]: It - is also the winner of Underscore's 2017 award for the most difficult functional programming term to work into a coherent English sentence. diff --git a/src/pages/case-studies/map-reduce/index.md b/src/pages/case-studies/map-reduce/index.md index 8606c179..a2f6d6cc 100644 --- a/src/pages/case-studies/map-reduce/index.md +++ b/src/pages/case-studies/map-reduce/index.md @@ -417,14 +417,15 @@ def parallelFoldMap[A, B: Monoid] } } -val result: Future[Int] = - parallelFoldMap((1 to 1000000).toVector)(identity) +val result: Future[Long] = + parallelFoldMap((1L to 1000000L).toVector)(identity) ``` ```scala mdoc Await.result(result, 1.second) ``` +We used Long instead of Int in the example run above, to avoid numeric overflow. We can re-use our definition of `foldMap` for a more concise solution. Note that the local maps and reduces in steps 3 and 4 of Figure [@fig:map-reduce:parallel-fold-map] @@ -458,8 +459,8 @@ def parallelFoldMap[A, B: Monoid] } } -val result: Future[Int] = - parallelFoldMap((1 to 1000000).toVector)(identity) +val result: Future[Long] = + parallelFoldMap((1L to 1000000L).toVector)(identity) ``` ```scala mdoc @@ -474,7 +475,7 @@ the method is also available as part of the `Foldable` type class we discussed in Section [@sec:foldable]. Reimplement `parallelFoldMap` using Cats' -`Foldable` and `Traverseable` type classes. +`Foldable` and `Traversable` type classes.
We'll restate all of the necessary imports for completeness: @@ -544,7 +545,7 @@ Our algorithm followed three steps: Our toy system emulates the batching behaviour of real-world map-reduce systems such as Hadoop. However, in reality we are running all of our work -on a single machine where communcation between nodes is negligible. +on a single machine where communication between nodes is negligible. We don't actually need to batch data to gain efficient parallel processing of a list. We can simply map using a `Functor` and reduce using a `Monoid`. diff --git a/src/pages/case-studies/parser/applicative.md b/src/pages/case-studies/parser/applicative.md index 671e622c..29ac9cb9 100644 --- a/src/pages/case-studies/parser/applicative.md +++ b/src/pages/case-studies/parser/applicative.md @@ -142,7 +142,7 @@ Let's implement an instance of Scalaz's `Applicative` type class for our `Parser ### Exercise: Applicative Parser -Define a typeclass instance of `Applicative` for `Parser`. You must implement the following trait: +Define a type class instance of `Applicative` for `Parser`. You must implement the following trait: ~~~ scala Applicative[Parser] { @@ -162,7 +162,7 @@ Hints:
-The usual place to define typeclass instances is as implicit elements on the companion object, in this case the `Parser` object. Here's my implementation: +The usual place to define type class instances is as implicit elements on the companion object, in this case the `Parser` object. Here's my implementation: ~~~ scala val identity: Parser[Unit] = diff --git a/src/pages/case-studies/validation/check.md b/src/pages/case-studies/validation/check.md index 95519aa3..111c1593 100644 --- a/src/pages/case-studies/validation/check.md +++ b/src/pages/case-studies/validation/check.md @@ -39,7 +39,7 @@ As we said in [Essential Scala][link-essential-scala], there are two functional programming patterns that we should consider when defining a trait: -- we can make it a typeclass, or; +- we can make it a type class, or; - we can make it an algebraic data type (and hence seal it). Type classes allow us to unify disparate data types with a common interface. diff --git a/src/pages/case-studies/validation/kleisli.md b/src/pages/case-studies/validation/kleisli.md index 91d0421e..13eb83f3 100644 --- a/src/pages/case-studies/validation/kleisli.md +++ b/src/pages/case-studies/validation/kleisli.md @@ -261,7 +261,7 @@ def checkPred[A](pred: Predicate[Errors, A]): Check[A, A] = ``` Our base predicate definitions are -essenitally unchanged: +essentially unchanged: ```scala mdoc:silent def longerThan(n: Int): Predicate[Errors, String] = @@ -307,7 +307,7 @@ val checkLeft: Check[String, String] = checkPred(longerThan(0)) val checkRight: Check[String, String] = - checkPred(longerThan(3) and contains('.')) + checkPred(longerThan(2) and contains('.')) val joinEmail: Check[(String, String), String] = check { diff --git a/src/pages/case-studies/validation/map.md b/src/pages/case-studies/validation/map.md index 88c4a703..c1b3835a 100644 --- a/src/pages/case-studies/validation/map.md +++ b/src/pages/case-studies/validation/map.md @@ -322,7 +322,7 @@ val h: A => C = f andThen g ``` A `Check` is basically a function `A => Validated[E, B]` -so we can define an analagous `andThen` method: +so we can define an analogous `andThen` method: ```scala trait Check[E, A, B] { @@ -627,7 +627,7 @@ val checkLeft: Check[Errors, String, String] = Check(longerThan(0)) val checkRight: Check[Errors, String, String] = - Check(longerThan(3) and contains('.')) + Check(longerThan(2) and contains('.')) val joinEmail: Check[Errors, (String, String), String] = Check { case (l, r) => diff --git a/src/pages/foldable-traverse/foldable.md b/src/pages/foldable-traverse/foldable.md index 576aef44..a201f3b9 100644 --- a/src/pages/foldable-traverse/foldable.md +++ b/src/pages/foldable-traverse/foldable.md @@ -41,7 +41,8 @@ Figure [@fig:foldable-traverse:fold] illustrates each direction. ![Illustration of foldLeft and foldRight](src/pages/foldable-traverse/fold.pdf+svg){#fig:foldable-traverse:fold} `foldLeft` and `foldRight` are equivalent -if our binary operation is associative. +if our binary operation is associative and initial accumulator is +monoid empty/identity value for the binary operation. For example, we can sum a `List[Int]` by folding in either direction, using `0` as our accumulator and addition as our operation: diff --git a/src/pages/functors/cats.md b/src/pages/functors/cats.md index 3ae4835c..b64d40b6 100644 --- a/src/pages/functors/cats.md +++ b/src/pages/functors/cats.md @@ -84,7 +84,7 @@ no matter what functor context it's in: ```scala mdoc:silent def doMath[F[_]](start: F[Int]) (implicit functor: Functor[F]): F[Int] = - start.map(n => n + 1 * 2) + start.map(n => (n + 1) * 2) import cats.instances.option._ // for Functor import cats.instances.list._ // for Functor diff --git a/src/pages/functors/contravariant-invariant-cats.md b/src/pages/functors/contravariant-invariant-cats.md index 71341612..4bb4d993 100644 --- a/src/pages/functors/contravariant-invariant-cats.md +++ b/src/pages/functors/contravariant-invariant-cats.md @@ -89,7 +89,7 @@ and a `combine` method that works as follows: We can implement `combine` using `imap`, passing functions of type `String => Symbol` and `Symbol => String` as parameters. -Here' the code, written out using +Here's the code, written out using the `imap` extension method provided by `cats.syntax.invariant`: diff --git a/src/pages/functors/summary.md b/src/pages/functors/summary.md index 5763e3dd..25e44433 100644 --- a/src/pages/functors/summary.md +++ b/src/pages/functors/summary.md @@ -33,7 +33,7 @@ transformations on large collections, a technique leveraged heavily in "map-reduce" frameworks like [Hadoop][link-hadoop]. We will investigate this approach in more detail in the -map-reduce case study later in Section [@sec:map-reduce]. +map-reduce case study later in Chapter [@sec:map-reduce]. The `Contravariant` and `Invariant` type classes are less widely applicable but are still useful diff --git a/src/pages/intro/contributors.md b/src/pages/intro/contributors.md index 63233cc3..7c30471b 100644 --- a/src/pages/intro/contributors.md +++ b/src/pages/intro/contributors.md @@ -8,6 +8,7 @@ and Richard Dallaway for his proof reading expertise. Here is an alphabetical list of contributors: Alessandro Marrella, +Alex Stangl, Cody Koeninger, Connie Chen, Conor Fennell, diff --git a/src/pages/links.md b/src/pages/links.md index 1a7b64bb..40c6dcee 100644 --- a/src/pages/links.md +++ b/src/pages/links.md @@ -114,7 +114,7 @@ [link-json]: http://json.org/ [link-kind-projector]: https://github.com/typelevel/kind-projector [link-map-reduce-monoid]: http://arxiv.org/abs/1304.7544 -[link-map-reduce]: http://research.google.com/archive/map-reduce.html +[link-map-reduce]: http://static.googleusercontent.com/media/research.google.com/es/us/archive/mapreduce-osdi04.pdf [link-mdoc]: https://github.com/scalameta/mdoc [link-monads-burritos]: http://blog.plover.com/prog/burritos.html [link-monocle]: http://julien-truffaut.github.io/Monocle/ diff --git a/src/pages/monads/cats.md b/src/pages/monads/cats.md index 97f9129c..42027cdb 100644 --- a/src/pages/monads/cats.md +++ b/src/pages/monads/cats.md @@ -40,7 +40,7 @@ See the [scaladoc][cats.Monad] for more information. ### Default Instances Cats provides instances for all the monads in the standard library -(`Option`, `List`, `Vector` and so on) via [`cats.instances`][cats.instances]: +(`Option`, `List`, `Vector`, and so on) via [`cats.instances`][cats.instances]: ```scala mdoc:silent import cats.instances.option._ // for Monad diff --git a/src/pages/monads/eval.md b/src/pages/monads/eval.md index 51e536fd..70475569 100644 --- a/src/pages/monads/eval.md +++ b/src/pages/monads/eval.md @@ -22,7 +22,7 @@ We can see the evaluation model using a computation with a visible side-effect. In the following example, the code to compute the value of `x` -happens at place where it is defined +happens at the place where it is defined rather than on access. Accessing `x` recalls the stored value without re-running the code. diff --git a/src/pages/monads/monad-error.md b/src/pages/monads/monad-error.md index ba5c46bc..23e91c7c 100644 --- a/src/pages/monads/monad-error.md +++ b/src/pages/monads/monad-error.md @@ -101,7 +101,7 @@ monadError.handleErrorWith(failure) { ``` If we know we can handle all possible errors -we can use `handleWith`. +we can use `handleError`. ```scala mdoc monadError.handleError(failure) { diff --git a/src/pages/monads/state.md b/src/pages/monads/state.md index b7d137d3..396dde41 100644 --- a/src/pages/monads/state.md +++ b/src/pages/monads/state.md @@ -165,14 +165,13 @@ carrying a *stack* of operands with us as we go: operate on them, and push the result in their place. This allows us to evaluate complex expressions without using parentheses. -For example, we can evaluate `(1 + 2) * 3)` as follows: +For example, we can evaluate `((1 + 2) * 3)` as follows: ```scala 1 2 + 3 * // see 1, push onto stack 2 + 3 * // see 2, push onto stack + 3 * // see +, pop 1 and 2 off of stack, // push (1 + 2) = 3 in their place -3 3 * // see 3, push onto stack 3 * // see 3, push onto stack * // see *, pop 3 and 3 off of stack, // push (3 * 3) = 9 in their place @@ -256,7 +255,7 @@ def operand(num: Int): CalcState[Int] = The `operator` function is a little more complex. We have to pop two operands off the stack -(having the second operand at the top of the stack)i +(having the second operand at the top of the stack) and push the result in their place. The code can fail if the stack doesn't have enough operands on it, but the exercise description allows us to throw an exception in this case: diff --git a/src/pages/monoids/cats.md b/src/pages/monoids/cats.md index 8c430d3e..4b9740fb 100644 --- a/src/pages/monoids/cats.md +++ b/src/pages/monoids/cats.md @@ -23,7 +23,7 @@ import cats.Semigroup *Cats Kernel?* Cats Kernel is a subproject of Cats -providing a small set of typeclasses +providing a small set of type classes for libraries that don't require the full Cats toolbox. While these core type classes are technically defined in the [`cats.kernel`][cats.kernel.package] package, diff --git a/src/pages/type-classes/anatomy.md b/src/pages/type-classes/anatomy.md index f61cb34a..522625da 100644 --- a/src/pages/type-classes/anatomy.md +++ b/src/pages/type-classes/anatomy.md @@ -89,7 +89,7 @@ In Scala this means any method that accepts instances of the type class as implicit parameters. Cats provides utilities that make type classes easier to use, -and you will sometimes seem these patterns in other libraries. +and you will sometimes see these patterns in other libraries. There are two ways it does this: *Interface Objects* and *Interface Syntax*. **Interface Objects**