Permalink
Browse files

Removed excerpts of text from the sections (#19)

  • Loading branch information...
1 parent 5a04144 commit 3f88e4a2cb43d102af2e964514bf58dc9dafaa4d @jdesiloniz jdesiloniz committed with raulraja Sep 15, 2016
@@ -15,50 +15,17 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
*
* The following set of sections represent the exercises contained in the book "Functional Programming in Scala",
* written by Paul Chiusano and Rúnar Bjarnason and published by Manning. This content library is meant to be used
- * in tandem with the book, although excerpts of the theory needed to complete them have been added to guide you.
+ * in tandem with the book. We use the same numeration for the exercises for you to follow them.
*
* For more information about "Functional Programming in Scala" please visit its
* <a href="https://www.manning.com/books/functional-programming-in-scala">official website</a>.
*
* = The Option data type =
*
- * Exceptions break referential transparency and introduce context dependence. Moreover, they are not type-safe,
- * hiding information about the fact that they may occur, to the developer and the compiler. We're going to explore
- * an alternative to exceptions without these drawbacks, without losing out on the primary benefit of exceptions:
- * they allow us to `consolidate and centralize error-handling logic`. The technique we use is based on an old idea:
- * instead of throwing an exception, we return a value indicating that an exceptional condition has occurred. instead
- * of using error codes, we introduce a new generic type for these “possibly defined values” and use higher-order
- * functions to encapsulate common patterns of handling and propagating errors.
+ * <b>Exercise 4.1</b>:
*
- * We're going to introduce a new type, `Option`. As with the previously explored `List`, this type also exists in
- * the Scala standard library, but we're re-creating it here for pedagogical purposes:
- *
- * {{{
- * sealed trait Option[+A]
- * case class Some[+A](get: A) extends Option[A]
- * case object None extends Option[Nothing]
- * }}}
- *
- * Option has two cases: it can be defined, in which case it will be a `Some`, or it can be undefined, in which case
- * it will be `None`.
- *
- * Let's consider an example on how we can use our new type. We're defining a function `mean` that computes the mean
- * of a list, which is undefined if the list is empty:
- */
-
- def optionMeanAssert(res0: Option[Double]): Unit = {
- def mean(xs: Seq[Double]): Option[Double] =
- if (xs.isEmpty) None
- else Some(xs.sum / xs.length)
-
- mean(Seq(1, 2, 3, 4, 5)) shouldBe Some(3.0)
- mean(Seq.empty) shouldBe res0
- }
-
- /**
- * `Option` can be thought of like a `List` that can contain at most one element, and many of the `List` functions we
- * saw earlier have analogous functions on `Option`. We're going to look at some of these functions, starting by `map`,
- * that applies a function `f` in the `Option` is not `None`:
+ * We're going to look at some of the functions available in the `Option`, starting by `map`, that applies a function
+ * `f` in the `Option` is not `None`:
*
* {{{
* def map[B](f: A => B): Option[B] = this match {
@@ -98,8 +65,7 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* def flatMap[B](f: A => Option[B]): Option[B] = map(f) getOrElse None
* }}}
*
- * By using `flatMap` we can chain operations that can also fail, as in the following example. Try to find out who is
- * managing each employee, if applicable:
+ * Try to find out who is managing each employee, if applicable:
*/
def optionFlatMapAssert(res0: (Option[Employee]) => Option[String]): Unit = {
@@ -111,10 +77,8 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
}
/**
- * The function `getOrElse` used above, tries to get the value contained in the Option, but if it's a `None`, it will
- * return the default value provided by the caller. The `B >: A` in the declaration tells that the `B` type parameter
- * must be a supertype of `A`. Furthermore, `default : => B` indicates that the argument is of type B, but won’t be
- * evaluated until it’s needed by the function.
+ * The function `getOrElse` tries to get the value contained in the Option, but if it's a `None`, it will
+ * return the default value provided by the caller:
*
* {{{
* def getOrElse[B>:A](default: => B): B = this match {
@@ -129,6 +93,8 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* {{{
* def orElse[B>:A](ob: => Option[B]): Option[B] = this map (Some(_)) getOrElse ob
* }}}
+ *
+ * Check how it works in the following exercise:
*/
def optionOrElseAssert(res0: Some[String], res1: Some[String], res2: Some[String]): Unit = {
@@ -139,7 +105,8 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
getManager(lookupByName("Foo")).orElse(Some("Mr. CEO")) shouldBe res2
}
- /** Finally, we can implement a `filter` function that will turn any `Option` into a `None` if it doesn't satisfy the
+ /**
+ * Finally, we can implement a `filter` function that will turn any `Option` into a `None` if it doesn't satisfy the
* provided predicate:
*
* {{{
@@ -159,6 +126,8 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
}
/**
+ * <b>Exercise 4.2:</b>
+ *
* Let's implement the `variance` function in terms of `flatMap`. If the mean of a sequence is `m`, the variance
* is the mean of `math.pow(x - m, 2)` for each element in the sequence:
*
@@ -169,39 +138,22 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
*/
/**
- * We may find in some situations when we need to combine two `Option` values using a binary function, so that if any
- * of those values is `None`, the result value is too; and otherwise it will be the result of applying the provided
- * function. We'll call this function `map2`, take a look at its implementation:
+ * <b>Exercise 4.3:</b>
+ *
+ * Let's write a generic function to combine two `Option` values , so that if any of those values is `None`, the
+ * result value is too; and otherwise it will be the result of applying the provided function:
*
* {{{
* def map2[A,B,C](a: Option[A], b: Option[B])(f: (A, B) => C): Option[C] =
* a flatMap (aa => b map (bb => f(aa, bb)))
* }}}
*
- * Let's see an example of its use. Let's write a function `parseInsuranceRateQuote` which takes the age and a number
- * of speeding tickets as strings, and attempts to call another function called `insuranceRateQuote` if parsing both
- * values is valid:
- *
- * {{{
- * def Try[A](a: => A): Option[A] =
- * try Some(a)
- * catch { case e: Exception => None }
- *
- * def parseInsuranceRateQuote( age: String, numberOfSpeedingTickets: String): Option[Double] = {
- * val optAge: Option[Int] = Try { age.toInt }
- * val optTickets: Option[Int] = Try { numberOfSpeedingTickets.toInt } map2(optAge, optTickes)(insuranceRateQuote)
- * }
- * }}}
+ * <b>Exercise 4.4:</b>
*
- * As `Try` will return an `Option` containing the value of the operation it encapsulates (or a `None` if it returns
- * an exception), to combine both values we need to make use of the new `map2` function we just implemented.
- */
-
- /**
* Let's continue by looking at a few other similar cases. For instance, the `sequence` function, which combines a list
- * of `Option`s into one `Option` containing a list of all the `Some` values in the original list. If the original
- * list contains `None` even once, the result of the function should be `None`. Otherwise the result should be a `Some`
- * with a list of all the values:
+ * of `Option`s into another `Option` containing a list of all the `Some`s in the original one. If the original
+ * list contains `None` at least once, the result of the function should be `None`. If not, the result should be a
+ * `Some` with a list of all the values:
*
* {{{
* def sequence(a: List[Option[A]]): Option[List[A]] = a match {
@@ -219,10 +171,10 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
}
/**
+ * <b>Exercise 4.5:</b>
+ *
* The last `Option` function we're going to explore is `traverse`, that will allow us to map over a list using a
- * function that might fail, returning `None` if applying it to any element of the list returns `None`. Note that we
- * want to avoid traversing the list twice (first to apply the provided function to each element, and another to
- * combine these `Option` values into an optional `List`:
+ * function that might fail, returning `None` if applying it to any element of the list returns `None`:
*
* {{{
* def traverse[A, B](a: List[A])(f: A => Option[B]): Option[List[B]] = a match {
@@ -263,39 +215,8 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
/**
* = The Either data type =
*
- * One thing you may have noticed with `Option` is that it doesn’t tell us anything about what went wrong in the case
- * of an exceptional condition. All it can do is give us `None`, indicating that there’s no value to be had. But
- * sometimes we want to know more. For example, we might want a `String` that gives more information, or if an
- * exception was raised, we might want to know what that error actually was.
- *
- * In this section, we’ll walk through a simple extension to `Option`, the `Either` data type, which lets us track a
- * reason for the failure. Let’s look at its definition:
- *
- * {{{
- * sealed trait Either[+E, +A]
- * case class Left[+E](value: E) extends Either[E, Nothing]
- * case class Right[+A](value: A) extends Either[Nothing, A]
- * }}}
- *
- * `Either` only has two cases, just like `Option`. The essential difference is that both cases carry a value. When
- * we use it to indicate success or failure, by convention the `Right` constructor is reserved for the success case
- * (a pun on “right,” meaning correct), and `Left` is used for failure.
+ * <b>Exercise 4.6:</b>
*
- * Let's look at the `mean` example again, this time returning a `String` in case of failure:
- */
-
- def eitherMeanAssert(res0: Right[Double], res1: Left[String]): Unit = {
- def mean(xs: IndexedSeq[Double]): Either[String, Double] =
- if (xs.isEmpty)
- Left("mean of empty list!")
- else
- Right(xs.sum / xs.length)
-
- mean(IndexedSeq(1.0, 2.0, 3.0, 4.0, 5.0)) shouldBe res0
- mean(IndexedSeq.empty) shouldBe res1
- }
-
- /**
* As we did with `Option`, let's implement versions of `map`, `flatMap`, `orElse` and `map2` on `Either` that
* operate on the `Right` value, starting with `map`:
*
@@ -409,8 +330,10 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
}
/**
- * `sequence` and `traverse` can also be implemented for `Either`. These should return the first error that's
- * encountered, if there is one.
+ * <b>Exercise 4.7:</b>
+ *
+ * `sequence` and `traverse` can also be implemented for `Either`. Those functions should return the first error that
+ * can be found, if there is one.
*
* {{{
* def traverse[E,A,B](es: List[A])(f: A => Either[E, B]): Either[E, List[B]] = es match {
Oops, something went wrong.

0 comments on commit 3f88e4a

Please sign in to comment.