我正在尝试将函数:A => B 应用于 Result[A] 来获取 Result[B],但出现了奇怪的类型错误。
found : Product with Serializable with this.Result[_ <: B]
required: this.Result[B]
我不知道如何解决这个问题。看起来 scala 正在尝试将函数的输出转换为字符串(可序列化),因为它找不到成功/失败和结果之间的转换?
简化的代码如下。我尝试附加显式类型信息,但代码无法编译。任何帮助将不胜感激!
sealed trait Result[A]{
def map[B](f: A => B) = this match{
case Success((a, rest)) => Success((f(a), rest))
case Failure(m) => Failure(m)
}
}
case class Success[A](result: (A, List[Char])) extends Result[A]
case class Failure[A](message: String) extends Result[A]
object Utils{
def map[A,B](r: Result[A], f: A => B):Result[B] = {
r.map(f)
}
}
最佳答案
解释最初的问题:您没有指定 Result.map
的返回类型,所以 Scala 必须推断它。为此,它会查看两个分支。第一个的返回类型是 Success[B]
。第二个的返回类型是 Failure[Nothing]
,因为 Scala 没有理由假设您的意思是 Failure[B](m)
那里!
所以现在它必须找到 Success[B]
都满足的类型和Failure[Nothing]
拟合(它们的最小上限)。好吧,它们都扩展了 Product
和Serializable
(因为它们是案例类)。它们还都扩展 Result
,但具有不同的类型参数。 Nothing
的最小上限和B
是 B
,所以它们都扩展 Result[_ <: B]
。这就是你最终得到的类型 map
:Product with Serializable with Result[_ <: B]
。
请注意,通过应用 Andy Hayden 的答案,您将得到 Product with Serializable with Result[B]
相反,不是Result[B]
这可能就是你想要的。为此,要么显式指定返回类型(即使没有协方差也可以工作,希望您现在可以明白原因),或者创建 Result
延长Product with Serializable
.
关于Scala 类型推断不适用于泛型案例类和 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37604813/