Skip to content

Commit

Permalink
Added language review fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Javier de Silóniz Sandino committed Aug 25, 2016
1 parent 6b0d257 commit 6a05feb
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 73 deletions.
38 changes: 19 additions & 19 deletions src/main/scala/fpinscalalib/ErrorHandlingSection.scala
Expand Up @@ -21,8 +21,8 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* of using error codes, we introduce a new generic type for these “possibly defined values” and use higher-order * 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. * functions to encapsulate common patterns of handling and propagating errors.
* *
* We introduce a new type, `Option`. As with the previously explored `List`, this type also exists in the Scala * We're going to introduce a new type, `Option`. As with the previously explored `List`, this type also exists in
* standard library, but we're re-creating it here for pedagogical purposes: * the Scala standard library, but we're re-creating it here for pedagogical purposes:
* *
* {{{ * {{{
* sealed trait Option[+A] * sealed trait Option[+A]
Expand All @@ -33,8 +33,8 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* Option has two cases: it can be defined, in which case it will be a `Some`, or it can be undefined, in which case * 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`. * it will be `None`.
* *
* Let's consider an example to use our new type. We're defining a function `mean` that computes the mean of a list, * Let's consider an example on how we can use our new type. We're defining a function `mean` that computes the mean
* which is undefined if the list is empty: * of a list, which is undefined if the list is empty:
*/ */


def optionMeanAssert(res0: Option[Double]): Unit = { def optionMeanAssert(res0: Option[Double]): Unit = {
Expand Down Expand Up @@ -89,7 +89,7 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* def flatMap[B](f: A => Option[B]): Option[B] = map(f) getOrElse None * def flatMap[B](f: A => Option[B]): Option[B] = map(f) getOrElse None
* }}} * }}}
* *
* By using `flatMap` we can chain operations that also can fail, as in the following example. Try to find out who is * 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: * managing each employee, if applicable:
*/ */


Expand All @@ -102,7 +102,7 @@ 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` will * 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 * 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 * 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. * evaluated until it’s needed by the function.
Expand Down Expand Up @@ -140,7 +140,7 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* } * }
* }}} * }}}
* *
* Try it out to discard those employees who belong to the IT department: * Test it out by discarding those employees who belong to the IT department:
*/ */


def optionFilterAssert(res0: Some[Employee], res1: Option[Employee], res2: Option[Employee]): Unit = { def optionFilterAssert(res0: Some[Employee], res1: Option[Employee], res2: Option[Employee]): Unit = {
Expand Down Expand Up @@ -189,7 +189,7 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
*/ */


/** /**
* Let's continue looking at a few other similar cases. For instance, the `sequence` function, which combines a list * 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 * 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` * 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: * with a list of all the values:
Expand All @@ -201,7 +201,7 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* } * }
* }}} * }}}
* *
* After taking a look at the implementation, check how it works in the following exercise: * After taking a look at the implementation, see how it works in the following exercise:
*/ */


def optionSequenceAssert(res0: Some[List[Int]], res1: Option[List[Int]]): Unit = { def optionSequenceAssert(res0: Some[List[Int]], res1: Option[List[Int]]): Unit = {
Expand Down Expand Up @@ -268,7 +268,7 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* case class Right[+A](value: A) extends Either[Nothing, A] * case class Right[+A](value: A) extends Either[Nothing, A]
* }}} * }}}
* *
* `Either` has only two cases, just like `Option`. The essential difference is that both cases carry a value. When * `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 * 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. * (a pun on “right,” meaning correct), and `Left` is used for failure.
* *
Expand Down Expand Up @@ -297,7 +297,7 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* } * }
* }}} * }}}
* *
* In the same fashion as `Option`, `map` allow us to chain operations on an `Either` without worrying about the * In the same fashion as `Option`, `map` allows us to chain operations on an `Either` without worrying about the
* possible errors that may arise, as the chain will stop if any error occurs. Let's try it out, by improving the * possible errors that may arise, as the chain will stop if any error occurs. Let's try it out, by improving the
* employee lookup function we implemented before, to use `Either` instead of `Option`. Try to use `map` on the * employee lookup function we implemented before, to use `Either` instead of `Option`. Try to use `map` on the
* `Either` type to obtain the department of each employee: * `Either` type to obtain the department of each employee:
Expand All @@ -318,9 +318,9 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
} }


/** /**
* `flatMap` behaves the same in `Either` as in `Option`, allowing us to chain operations that may also fail. Use it * `flatMap` behaves the same in `Either` as it does in `Option`, allowing us to chain operations that may also fail.
* to try to obtain the managers from each employee. Note that when calling our `getManager` function, we can find * Use it to try to obtain the managers from each employee. Note that when calling our `getManager` function, we can
* two different errors in its execution: * find two different errors in its execution:
*/ */


def eitherFlatMapAssert(res0: Right[String], res1: Left[String], res2: Left[String]): Unit = { def eitherFlatMapAssert(res0: Right[String], res1: Left[String], res2: Left[String]): Unit = {
Expand All @@ -347,7 +347,7 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* } * }
* }}} * }}}
* *
* Let's check how it behaves. Let's assume that everyone inside our company ends up responding to a "Mr. CEO" * Let's check out how it behaves. Let's assume that everyone inside our company ends up responding to a "Mr. CEO"
* manager. We can provide that logic with `orElse`: * manager. We can provide that logic with `orElse`:
*/ */


Expand Down Expand Up @@ -376,7 +376,7 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* } yield f(a,b1) * } yield f(a,b1)
* }}} * }}}
* *
* In this implementation, we can't report errors on both sides. To do that, we would need a new data type that could * In this implementation, we can't report errors on both sides. To do that, we would need a new data type that can
* hold a list of errors: * hold a list of errors:
* *
* {{{ * {{{
Expand Down Expand Up @@ -414,7 +414,7 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
* def sequence[E,A](es: List[Either[E,A]]): Either[E,List[A]] = traverse(es)(x => x) * def sequence[E,A](es: List[Either[E,A]]): Either[E,List[A]] = traverse(es)(x => x)
* }}} * }}}
* *
* We can try to lookup through a list of employee names to obtain a list of `Employees`: * We can attempt to obtain a record of employees names by looking up a list of `Employees`:
*/ */


def eitherTraverseAssert(res0: Right[List[Employee]], res1: Left[String]): Unit = { def eitherTraverseAssert(res0: Right[List[Employee]], res1: Left[String]): Unit = {
Expand All @@ -426,8 +426,8 @@ object ErrorHandlingSection extends FlatSpec with Matchers with org.scalaexercis
} }


/** /**
* As for `sequence`, we can create a `List` of employees we looked up by using the `lookupByNameViaEither`, and * As for `sequence`, we can create a `List` of the employees we looked up by using the `lookupByNameViaEither`, and
* find out if we were looking for some missing person: * find out if we were looking for a missing person:
*/ */


def eitherSequenceAssert(res0: Right[List[Employee]], res1: Left[String]): Unit = { def eitherSequenceAssert(res0: Right[List[Employee]], res1: Left[String]): Unit = {
Expand Down
32 changes: 16 additions & 16 deletions src/main/scala/fpinscalalib/FunctionalDataStructuresSection.scala
Expand Up @@ -13,7 +13,7 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s
/** /**
* = Singly linked lists = * = Singly linked lists =
* *
* First let's examine what's probably the most ubiquitous functional data structure, the singly linked list. The * Let's examine what's probably the most ubiquitous functional data structure, the singly-linked list to start. The
* definition here is identical in spirit to (though simpler than) the `List` data type defined in Scala's standard * definition here is identical in spirit to (though simpler than) the `List` data type defined in Scala's standard
* library. * library.
* *
Expand All @@ -40,7 +40,7 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s
* }}} * }}}
* *
* The definition of the data type begins with the keywords `sealed trait`. In general, we introduce a data type with * The definition of the data type begins with the keywords `sealed trait`. In general, we introduce a data type with
* the `trait` keyword. A `trait` is a an abstract interface that may optionally contain implementations of some * the `trait` keyword. A `trait` is an abstract interface that may optionally contain implementations of some
* methods. There are two such implementations, or data constructors, of `List`, to represent the two possible forms a * methods. There are two such implementations, or data constructors, of `List`, to represent the two possible forms a
* `List` can take. A `List` can be empty (denoted by the data constructor `Nil`), or it can be nonempty, denoted by * `List` can take. A `List` can be empty (denoted by the data constructor `Nil`), or it can be nonempty, denoted by
* the data constructor `Cons` (traditionally short for `construct`). A nonempty list consists of an initial element, * the data constructor `Cons` (traditionally short for `construct`). A nonempty list consists of an initial element,
Expand All @@ -53,7 +53,7 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s
* `List`. Both definitions make use of pattern matching. * `List`. Both definitions make use of pattern matching.
* *
* As you might expect, the `sum` function states that the sum of an empty list is 0, and the sum of a nonempty list * As you might expect, the `sum` function states that the sum of an empty list is 0, and the sum of a nonempty list
* is the first element, `x`, plus the sum of the remaining elements, `xs`. Likewise the `product` definition states * is the first element, `x`, plus the sum of the remaining elements, `xs`. Likewise, the `product` definition states
* that the product of an empty list is `1.0`, the product of any other nonempty list starting with `0.0` is `0.0`, * that the product of an empty list is `1.0`, the product of any other nonempty list starting with `0.0` is `0.0`,
* and the product of any other nonempty list is the first element multiplied by the product of the remaining elements. * and the product of any other nonempty list is the first element multiplied by the product of the remaining elements.
* *
Expand Down Expand Up @@ -111,7 +111,7 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s
* } * }
* }}} * }}}
* *
* Taking a look at its implementation, check its behaviour on the following cases: * After taking a look at its implementation, check out its behaviour on the following cases:
*/ */


def listTakeAssert(res0: List[Int], res1: List[Int]) { def listTakeAssert(res0: List[Int], res1: List[Int]) {
Expand All @@ -121,7 +121,7 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s


/** /**
* Using the same idea, we can implement the function `setHead` for replacing the first element of a List with a * Using the same idea, we can implement the function `setHead` for replacing the first element of a List with a
* a different value: * different value:
* *
* {{{ * {{{
* def setHead[A](l: List[A], h: A): List[A] = l match { * def setHead[A](l: List[A], h: A): List[A] = l match {
Expand Down Expand Up @@ -173,7 +173,7 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s
* } * }
* }}} * }}}
* *
* Check how it works with the following examples: * See how it works with the following examples:
*/ */


def listDropWhileAssert(res0: List[Int], res1: List[Int], res2: List[Int], res3: List[Int]) { def listDropWhileAssert(res0: List[Int], res1: List[Int], res2: List[Int], res3: List[Int]) {
Expand All @@ -185,7 +185,7 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s


/** /**
* In the same fashion, let's implement another function `init` that returns a `List` consisting of all but the last * In the same fashion, let's implement another function `init` that returns a `List` consisting of all but the last
* element of a `List`. Take a note that this function can't be implemented in constant time like `tail`. * element of a `List`. It should be noted that this function cannot be implemented in constant time like `tail`.
* *
* {{{ * {{{
* def init[A](l: List[A]): List[A] = * def init[A](l: List[A]): List[A] =
Expand All @@ -207,8 +207,8 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s
/** /**
* = Recursion over lists and generalizing to higher-order functions = * = Recursion over lists and generalizing to higher-order functions =
* *
* Let’s look again at the implementations of sum and product. We’ve simplified the product implementation slightly, * Once again, let’s take a look at the implementations of `sum` and `product`. We’ve simplified the product
* so as not to include the “short-circuiting” logic of checking for 0.0: * implementation slightly, so as not to include the “short-circuiting” logic of checking for 0.0:
* *
* {{{ * {{{
* def sum(ints: List[Int]): Int = ints match { * def sum(ints: List[Int]): Int = ints match {
Expand All @@ -227,7 +227,7 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s
* of sum, 1.0 in the case of product), and the operation to combine results (+ in the case of sum, * in the case of * of sum, 1.0 in the case of product), and the operation to combine results (+ in the case of sum, * in the case of
* product). * product).
* *
* We can do better by generalizing those functions, by implementing a `foldRight`. This function will take as * We can improve things by generalizing those functions, by implementing a `foldRight`. This function will take on as
* arguments the value to return in the case of the empty list, and the function to add an element to the result in * arguments the value to return in the case of the empty list, and the function to add an element to the result in
* the case of a nonempty list: * the case of a nonempty list:
* *
Expand Down Expand Up @@ -262,8 +262,8 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s
} }


/** /**
* Now that we know how `foldRight` works, try to think what happens when you pass `Nil` and `Cons` themselves to * Now that we know how `foldRight` works, try to think about what happens when you pass `Nil` and `Cons` themselves
* `foldRight`. * to `foldRight`.
*/ */


def listFoldRightNilConsAssert(res0: List[Int]) { def listFoldRightNilConsAssert(res0: List[Int]) {
Expand Down Expand Up @@ -414,8 +414,8 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s
*/ */


/** /**
* Let's apply the same principle as in `map` to remove elements from a list, starting with a function to remove all * Let's apply the same principle as we use in `map` to remove elements from a list, starting with a function to
* odd numbers from a List[Int]: * remove all odd numbers from a List[Int]:
*/ */
def listRemoveOdds(res0: Int, res1: Int): Unit = { def listRemoveOdds(res0: Int, res1: Int): Unit = {
def removeOdds(l: List[Int]): List[Int] = def removeOdds(l: List[Int]): List[Int] =
Expand Down Expand Up @@ -494,7 +494,7 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s
} }


/** /**
* As a final example to work with lists, let's implement a `hasSubsequence` function for checking whether a `List` * As a final example for working with lists, let's implement a `hasSubsequence` function for checking whether a `List`
* contains another `List` as a subsequence. For instance, `List(1, 2, 3, 4)` would have `List(1, 2)`, `List(2, 3)` * contains another `List` as a subsequence. For instance, `List(1, 2, 3, 4)` would have `List(1, 2)`, `List(2, 3)`
* and `List(4)` as subsequences, among others: * and `List(4)` as subsequences, among others:
* *
Expand All @@ -514,7 +514,7 @@ object FunctionalDataStructuresSection extends FlatSpec with Matchers with org.s
* } * }
* }}} * }}}
* *
* Take a deep look at the implementation of this function, and then try it out in the next exercise: * Take a thorough look at the implementation of this function, and then try it out in the next exercise:
*/ */


def listHasSubsequenceAssert(res0: Boolean, res1: Boolean, res2: Boolean): Unit = { def listHasSubsequenceAssert(res0: Boolean, res1: Boolean, res2: Boolean): Unit = {
Expand Down
18 changes: 9 additions & 9 deletions src/main/scala/fpinscalalib/FunctionalStateSection.scala
Expand Up @@ -74,8 +74,8 @@ object FunctionalStateSection extends FlatSpec with Matchers with org.scalaexerc
* *
* = Making stateful APIs pure = * = Making stateful APIs pure =
* *
* This problem of making seemingly stateful APIs pure comes up frequently, and we can always deal with it in this * Making seemingly stateful APIs pure is a problem that comes up frequently. We can always handle this in the same
* same way. For instance: * way, for instance:
* *
* {{{ * {{{
* class Foo { * class Foo {
Expand Down Expand Up @@ -324,8 +324,8 @@ object FunctionalStateSection extends FlatSpec with Matchers with org.scalaexerc
} }


/** /**
* We can also rewrite `map` and `map2` in terms of `flatMap`. The fact that this is possible is what we’re referring * We can also rewrite `map` and `map2` in terms of `flatMap`. The fact that this is possible is why we say that
* to when we say that `flatMap` is more powerful than `map` and `map2`. * `flatMap` is more powerful than `map` and `map2`.
* *
* {{{ * {{{
* def _map[A,B](s: Rand[A])(f: A => B): Rand[B] = * def _map[A,B](s: Rand[A])(f: A => B): Rand[B] =
Expand All @@ -334,8 +334,8 @@ object FunctionalStateSection extends FlatSpec with Matchers with org.scalaexerc
* flatMap(ra)(a => map(rb)(b => f(a, b))) * flatMap(ra)(a => map(rb)(b => f(a, b)))
* }}} * }}}
* *
* As a final example, let's revisit our previously written functions to implement a function that roll a six-sided * As a final example, lets revisit the functions we previously wrote and implement a function that will roll a
* die: * six-sided die:
*/ */


def randomRollDie(res0: Int): Unit = { def randomRollDie(res0: Int): Unit = {
Expand Down Expand Up @@ -370,8 +370,8 @@ object FunctionalStateSection extends FlatSpec with Matchers with org.scalaexerc
* case class State[S,+A](run: S => (A,S)) * case class State[S,+A](run: S => (A,S))
* }}} * }}}
* *
* Now we have a single, general-purpose type, and using this type we can write general-purpose functions for * Now we have a single, general-purpose type and can use it to write general-purpose functions for capturing common
* capturing common patterns of stateful programs. We can now just make `Rand` a type alias for `State`: * patterns of stateful programs. We can now make `Rand` a type alias for `State`:
* *
* {{{ * {{{
* type Rand[A] = State[RNG, A] * type Rand[A] = State[RNG, A]
Expand Down Expand Up @@ -411,7 +411,7 @@ object FunctionalStateSection extends FlatSpec with Matchers with org.scalaexerc
* The rules of the machine are as follows: * The rules of the machine are as follows:
* *
* - Inserting a coin into a locked machine will cause it to unlock if there’s any candy left. * - Inserting a coin into a locked machine will cause it to unlock if there’s any candy left.
* - Turning the knob on an unlocked machine will cause it to dispense candy and become locked. * - Turning the knob on an unlocked machine will cause it to dispense candy and then lock.
* - Turning the knob on a locked machine or inserting a coin into an unlocked machine does nothing. * - Turning the knob on a locked machine or inserting a coin into an unlocked machine does nothing.
* - A machine that’s out of candy ignores all inputs. * - A machine that’s out of candy ignores all inputs.
* *
Expand Down

0 comments on commit 6a05feb

Please sign in to comment.