我有以下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
?
答案 0 :(得分:0)
scala如何知道在
中使用替代this
a
(即aa
)
aa
未被this
取代。 aa
替换为字符串"right"
。
替换工作由flatMap
完成:
case Right(r) => f(r)
flatMap
检查Either
的此实例是Right
还是Left
。如果是Right
,则会将其内容(字符串"right"
)提供给函数f
(aa => b map (bb => f(aa, bb))
)。
答案 1 :(得分:0)
scala如何知道将此替换(即a)替换为aa in 这行代码:这个flatMap(aa => b map(bb => f(aa,bb)))中的 map2功能?
不是。这是怎么回事:
Either[EE,B]
,称之为aa
并计算b map (bb => f(aa, bb)
。 b
和f
取自父作用域。this.flatMap
被调用。阅读有关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 => .....)
,你几乎回家了!