我想初始化一个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]
Run Code Online (Sandbox Code Playgroud)
我显然被迫冗长地提供的两面类型Either:
List(5, 42, 7).foldLeft(Left("empty"): Either[String, Int]) {
case (Left(_), i) => Right(i)
case (Right(s), i) => Right(s + i)
}
Run Code Online (Sandbox Code Playgroud)
以类似的方式,我可以使用Option.empty[Int]初始化None为Option[Int],是否可以将初始化Left("smthg")为Either[String, Int]?
Xav*_*hot 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")
Run Code Online (Sandbox Code Playgroud)
这同样适用于Right一侧withLeft:
Right(42).withLeft[String]
// Either[String, Int] = Right(42)
Run Code Online (Sandbox Code Playgroud)
在您的情况下:
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)
Run Code Online (Sandbox Code Playgroud)
为了补充Xavier的答案,猫还提供了用于创建的实用方法Either,例如,我们可以执行以下操作:
import cats.implicits._
val right = 7.asRight[String] // Either[String, Int]
val left: = "hello cats".asLeft[Int] // Either[String, Int]
Run Code Online (Sandbox Code Playgroud)
如果我们的项目使用的是Scala 2.12或更低版本,这可能会很有用。
如果我们不需要整个cats库,我们当然可以只为其中一个借用扩展功能:
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)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
99 次 |
| 最近记录: |