此代码(https://ideone.com/6y81ZT)
object Main extends App {
import scala.util.Try
case class Result[T](value :T)
def hi() = "hi"
def safer[T](f : () => T) : Try[Result[Option[T]]] = {
Try(hi)
.map((r) => Result(Some(r)))
.orElse(Try(Result(None)))
}
safer(hi)
}产生编译错误:
Main.scala:12: error: type mismatch; found :
scala.util.Try[Main.Result[_ >: Some[String] with Option[T] <: Option[Any]]]
required: scala.util.Try[Main.Result[Option[T]]]如何理解这一信息?
发布于 2015-09-02 20:51:27
有几个问题。
首先,将hi传递给Try.apply,这会导致将其固定到Try[String]而不是Try[T]。
第二个错误来自Result(Some(r)),编译器在那里期待Result[Option[T]]。lambda内部的类型过早地被钉在Result[Some[T]]上,这使得orElse推断出奇怪的复合类型。
Try(f())
.map(r => Result(Option(r))) // Try[Result[Some[T]]]
.orElse(Try(Result(None))) // Try[Result[None]]当(注意推断的类型)时也会发生这种情况:
scala> Try(1).map(r => Result(Some(r))).orElse(Try(Result(None)))
res6: scala.util.Try[Result[_ >: Some[Int] with None.type <: Option[Int]]] = Success(Result(Some(1)))如果Result在T上是协变的(请注意所希望的类型正在推断),上述情况就不会发生:
case class Result[+T](value: T)
scala> Try(1).map(r => Result(Some(r))).orElse(Try(Result(None)))
res7: scala.util.Try[Result[Option[Int]]] = Success(Result(Some(1)))在不更改Result的情况下,这样做是可行的:
def safer[T](f: () => T) : Try[Result[Option[T]]] = {
Try(f())
.map(r => Result(Option(r)))
.orElse(Try(Result(None)))
}没有必要将外部Try保持在返回类型中,因为您永远不会实际返回失败。(它总是由Result(None)恢复的。
您可以简化代码--您这样做了:
def safer[T](f: () => T) : Result[Option[T]] = Result(Try(f()).toOption)https://stackoverflow.com/questions/32362466
复制相似问题