这个scala代码的内容正在发生什么?

时间:2015-12-02 15:58:10

标签: scala

我有以下scala代码(来自FP In Scala一书):

import scala.{Option => _, Either => _, Left => _, Right => _, _} // hide std library `Option` and `Either`, since we are writing our own in this chapter

case class Left[+E](get: E) extends Either[E,Nothing]
case class Right[+A](get: A) extends Either[Nothing,A]

sealed trait Either[+E,+A] {
 def map[B](f: A => B): Either[E, B] = this match {
   case Right(r) => Right(f(r))
   case Left(e) => Left(e)
 }

 def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B] = this match {
   case Right(r) => f(r)
   case Left(e) => Left(e)
 }

 def map2[EE >: E, B, C](b: Either[EE, B])(f: (A, B) => C): Either[EE, C] = {
    this flatMap(aa => b map (bb => f(aa, bb)))
 }

}

我想知道当我像这样调用map2时会发生什么:

val b = fpinscala.errorhandling.Right(2)
val a = fpinscala.errorhandling.Right("right")
val f = (a: String, b:Int) => a + b
a.map2(b)(f)

scala如何知道在代码行this中使用替换a(即aa):this flatMap(aa => b map (bb => f(aa, bb)))函数中的map2

3 个答案:

答案 0 :(得分:0)

  

scala如何知道在this

中使用替代a(即aa

aa未被this取代。 aa替换为字符串"right"

替换工作由flatMap完成:

case Right(r) => f(r)

flatMap检查Either的此实例是Right还是Left。如果是Right,则会将其内容(字符串"right")提供给函数faa => b map (bb => f(aa, bb)))。

答案 1 :(得分:0)

  

scala如何知道将此替换(即a)替换为aa in   这行代码:这个flatMap(aa => b map(bb => f(aa,bb)))中的   map2功能?

不是。这是怎么回事:

  1. 正在构建一个闭包,它接受Either[EE,B],称之为aa并计算b map (bb => f(aa, bb)bf取自父作用域。
  2. 鉴于该函数作为参数,
  3. this.flatMap被调用。
  4. 阅读有关Scala闭包的更多信息: - )

答案 2 :(得分:0)

@jcm,看看这是否有意义。

a.map2(b)(f)

我们正在调用map2对象的a方法。方法代码a内部现在被引用为this

this flatMap(aa => b map (bb => f(aa, bb)))

现在我们正在调用flatMap对象的this方法(仍为a)。

flatMap作为一个论点是什么?它需要一个函数,一个带有参数的函数(某种类型,我们将其称为“A”)并返回Either。这意味着括号之间的所有内容都是该函数。该函数没有名称(即没有def语句)所以它通常被称为匿名函数。

该函数需要参数。此代码aa =>标识参数,以便稍后可以在函数中引用它。 “aa”只是一个任意名称。我们可以使用“thisthat”或“xyz”。

aa包含的值来自何处?它出自this。请考虑以下代码。

List(4,7,9).map(x => 42 - x)

在这种情况下,map调用匿名函数三次,对List中的每个值调用一次。每次调用函数时,x都会接受一个新值(前4个,然后是7个,然后是9个)。

如果这一切都有意义,那么将同样的逻辑应用于b map (bb => .....),你几乎回家了!