Scala 尝试和奇怪的行为

Scala Try and Either Weird Behavior

所以我在 Scala 中使用 M 类型,并提出了以下关于 TryEither 的内容:

def brokers(throw1: () => List[Int], throw2: List[Int] => List[String]) = {
  println("brokers ===> " +
    (Try(throw1())
      .toEither
      .filterOrElse(!_.isEmpty, Nil)
      .flatMap(xs => Try(throw2(xs)).toEither) match {
        case Right(s) => s
        case Left(f) => throw f.asInstanceOf[Throwable]
      })
    )
}

还有一些测试 运行s:

brokers(() => List(1, 2, 3), (xs: List[Int]) => xs.map(_.toString))
brokers(() => Nil, (xs: List[Int]) => throw new RuntimeException("throw2"))
brokers(() => Nil, (xs: List[Int]) => xs.map(_.toString))
brokers(() => throw new RuntimeException("throw1"), (xs: List[Int]) => xs.map(_.toString))
brokers(() => List(1, 2, 3), (xs: List[Int]) => throw new RuntimeException("throw2"))

但是:

  1. throw f 无法编译:"Expression of type Serializable doesn't conform to expected type Throwable"。因此演员表。
  2. 样本异常 运行 2:

Exception in thread "main" java.lang.ClassCastException: scala.collection.immutable.Nil$ cannot be cast to java.lang.Throwable at Practice$.brokers(Practice.scala:57) at Practice$.delayedEndpoint$Practice(Practice.scala:63)

为什么,Scala,为什么?

回答我自己的问题,结果 Either.filterOrElse 并不是我想的那样。如果谓词不匹配,filterOrElse 实际上会将 Either[A, B] 转换为 Either[AA, B],其中 AA 是提供给 filterOrElse 的 "zero" 元素。在我的例子中,它将 Either[Throwable,List[Int]] = Right(List()) 转换为 Either[java.io.Serializable,List[Int]] = Left(List())。因此编译错误,与 case Left 的匹配和最终的异常。 Serializable 一定来自逆变类型参数 AA >: A,因为猜猜看,ThrowableList 的第一个公共超类型是 Serializable.

我已为此提交 SI-10044;看看他们怎么说。