Scala,神秘编译器错误:找到:结果[\ugt;:带有选项[T]<;:选项[Any]]的某些[String]必需:结果[Option[T]]

Scala,神秘编译器错误:找到:结果[\ugt;:带有选项[T]<;:选项[Any]]的某些[String]必需:结果[Option[T]],scala,Scala,此代码() 生成编译错误: 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]]] Main.scala:12:错误:类型不匹配;发现: scala.util.Try[Main.Result[\

此代码()

生成编译错误:

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]]]
Main.scala:12:错误:类型不匹配;发现:

scala.util.Try[Main.Result[\u>:带有选项[T]的一些[String]存在一些问题

首先,您将
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]]
以下情况也会发生(请注意推断的类型):

在不更改
结果的情况下
,此操作有效:

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)
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)))
def safer[T](f: () => T) : Try[Result[Option[T]]] = {
    Try(f())
        .map(r => Result(Option(r)))
        .orElse(Try(Result(None)))
}
def safer[T](f: () => T) : Result[Option[T]] = Result(Try(f()).toOption)