如何将Either初始化为Right并指定Left的类型?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (12)

我想初始化一个Eitherto 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]

提问于
用户回答回答于

为了补充Xavier的答案,还提供了用于创建的实用方法Either,例如,我们可以:

import cats.implicits._

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

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

如果我们的项目使用scala 2.12或更低版本,它可能会有用。

如果我们不需要整个库,我们当然可以只使用扩展函数

implicit class EitherIdOps[A](private val obj: A) extends AnyVal {

  /** Wrap a value in `Left`. */
  def asLeft[B]: Either[A, B] = Left(obj)

  /** Wrap a value in `Right`. */
  def asRight[B]: Either[B, A] = Right(obj)

}
用户回答回答于

启动时Scala 2.13Left附带一个Left#withRight允许向上Left[A, Nothing]转换的方法Either[A, B]

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

同样适用于Right侧面和withLeft

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)

扫码关注云+社区

领取腾讯云代金券