Scala 将“flatMap”转换为“for comprehension”,使用
给定一个[String,Int]: 我可以使用flatMap编写以下代码: 但是,对于理解版,我做错了什么 ifa==100 Leftfoo else Righta是一个[String,Int],而不是LeftProjection或RightProjection,因此它没有map或flatMap。您还需要对其进行投影:Scala 将“flatMap”转换为“for comprehension”,使用,scala,Scala,给定一个[String,Int]: 我可以使用flatMap编写以下代码: 但是,对于理解版,我做错了什么 ifa==100 Leftfoo else Righta是一个[String,Int],而不是LeftProjection或RightProjection,因此它没有map或flatMap。您还需要对其进行投影: for { a <- z.right _ <- (if(a == 100) Left("foo") else Right(a)).right } yi
for {
a <- z.right
_ <- (if(a == 100) Left("foo") else Right(a)).right
} yield a
该衬里与单衬里的区别在于,单衬里相当于:
for {
a <- z.right
} yield (if(a == 100) Left("foo") else Right(a))
。。它的末尾没有额外的映射。ifa==100 Leftfoo else Righta是一个[String,Int],而不是LeftProjection或RightProjection,因此它没有map或flatMap。您还需要对其进行投影:
for {
a <- z.right
_ <- (if(a == 100) Left("foo") else Right(a)).right
} yield a
该衬里与单衬里的区别在于,单衬里相当于:
for {
a <- z.right
} yield (if(a == 100) Left("foo") else Right(a))
。。最后没有额外的地图。我认为这个问题的公认答案现在已经过时了 自Scala2.12以来,默认情况下,这两种方法都是右偏的。 因此,要么定义了map和flatMap
/** Binds the given function across `Left`.
*
* {{{
* Left(12).left.flatMap(x => Left("scala")) // Left("scala")
* Right(12).left.flatMap(x => Left("scala")) // Right(12)
* }}}
* @param f The function to bind across `Left`.
*/
def flatMap[A1, B1 >: B](f: A => Either[A1, B1]): Either[A1, B1] = e match {
case Left(a) => f(a)
case _ => e.asInstanceOf[Either[A1, B1]]
}
/** Maps the function argument through `Left`.
*
* {{{
* Left(12).left.map(_ + 2) // Left(14)
* Right[Int, Int](12).left.map(_ + 2) // Right(12)
* }}}
*/
def map[A1](f: A => A1): Either[A1, B] = e match {
case Left(a) => Left(f(a))
case _ => e.asInstanceOf[Either[A1, B]]
}
因此,您不必使用RightProjection,因为默认情况下这两个选项都是右偏的。所以下面的代码是有效的
val z: Either[String, Int] = Right(100)
val ans = for {
a <- z
_ <- if (a == 100) Left("foo") else Right(a)
} yield a
希望这能有所帮助。我认为这个问题的公认答案现在已经过时了 自Scala2.12以来,默认情况下,这两种方法都是右偏的。 因此,要么定义了map和flatMap
/** Binds the given function across `Left`.
*
* {{{
* Left(12).left.flatMap(x => Left("scala")) // Left("scala")
* Right(12).left.flatMap(x => Left("scala")) // Right(12)
* }}}
* @param f The function to bind across `Left`.
*/
def flatMap[A1, B1 >: B](f: A => Either[A1, B1]): Either[A1, B1] = e match {
case Left(a) => f(a)
case _ => e.asInstanceOf[Either[A1, B1]]
}
/** Maps the function argument through `Left`.
*
* {{{
* Left(12).left.map(_ + 2) // Left(14)
* Right[Int, Int](12).left.map(_ + 2) // Right(12)
* }}}
*/
def map[A1](f: A => A1): Either[A1, B] = e match {
case Left(a) => Left(f(a))
case _ => e.asInstanceOf[Either[A1, B]]
}
因此,您不必使用RightProjection,因为默认情况下这两个选项都是右偏的。所以下面的代码是有效的
val z: Either[String, Int] = Right(100)
val ans = for {
a <- z
_ <- if (a == 100) Left("foo") else Right(a)
} yield a
希望这有帮助