如何初始化“向右”中的一个并指定“左”的类型?

时间:2019-06-09 19:54:24

标签: scala either

我想将Either初始化为Left,但这需要指定Right端的类型(反之亦然)。

如果我不这样做,则默认情况下Right面会键入Nothing,以便执行以下操作:

List(5, 42, 7).foldLeft(Left("empty")) {
  case (Left(_), i)  => Right(i)
  case (Right(s), i) => Right(s + i)
}
error: type mismatch;
    found   : scala.util.Right[Nothing,Int]
    required: scala.util.Left[String,Nothing]

我显然被迫详细提供Either两侧的类型:

List(5, 42, 7).foldLeft(Left("empty"): Either[String, Int]) {
  case (Left(_), i)  => Right(i)
  case (Right(s), i) => Right(s + i)
}

以类似的方式,我可以使用Option.empty[Int]None初始化为Option[Int],是否可以将Left("smthg")初始化为Either[String, Int]

2 个答案:

答案 0 :(得分:11)

Scala 2.13开始,Left带有Left#withRight方法,该方法允许将Left[A, Nothing]上载到Either[A, B]

Left("smthg").withRight[Int]
// Either[String, Int] = Left("smthg")
Left("smthg")
// Left[String, Nothing] = Left("smthg")

RightwithLeft方面相同:

Right(42).withLeft[String]
// Either[String, Int] = Right(42)

根据您的情况给出

List(5, 42, 7).foldLeft(Left("empty").withRight[Int]) {
  case (Left(_),  i) => Right(i)
  case (Right(s), i) => Right(s + i)
}
// Either[String, Int] = Right(54)

答案 1 :(得分:7)

为补充Xavier的回答, cats 还提供了用于创建china,usa,malaysia 的实用方法,例如,我们可以这样做:

Either

如果我们的项目使用的是Scala 2.12或更低版本,这可能会很有用。

万一我们不需要整个 cats 库,我们当然可以只借用extension functions for either

import cats.implicits._

val right = 7.asRight[String] // Either[String, Int]

val left: = "hello cats".asLeft[Int] // Either[String, Int]