我希望将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]
发布于 2019-06-10 03:54:24
从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")
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)
发布于 2019-06-10 04:48:00
为了补充泽维尔的答案,cats还提供了创建Either
的实用方法,例如,我们可以这样做:
import cats.implicits._
val right = 7.asRight[String] // Either[String, Int]
val left: = "hello cats".asLeft[Int] // Either[String, Int]
如果我们的项目使用的是scala 2.12或更低版本,它可能会很有用。
如果我们不需要整个cats库,当然,我们可以只借用extension functions for either
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)
}
https://stackoverflow.com/questions/56517934
复制相似问题