Scala 类型推断不适用于泛型案例类和 lambda

标签 scala generics types lambda

我正在尝试将函数: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]拟合(它们的最小上限)。好吧,它们都扩展了 ProductSerializable (因为它们是案例类)。它们还都扩展 Result ,但具有不同的类型参数。 Nothing 的最小上限和BB ,所以它们都扩展 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/

相关文章:

java - Java 整数数组的高性能集合类数据结构

c - 当指针未指向正确的类型时,为什么 gcc 允许取消引用。为什么还要有类型?

Go:接口(interface)作为返回值

scala - 是否可以从 intellij 运行 giter8 模板?

scala - 如何在运行应用程序或测试用例时将JVM选项传递给SBT以使用?

c# - Reflection.Emit 泛型基类泛型方法调用

c# - 使用带有泛型类的 ContextBuilder 使用 Entity Framework 4 创建 EDMX/DB-Schema 的异常

arrays - 如何在 Rust 中引入数组长度的类型参数?

methods - 静态类型语言中的多界方法?

scala - Flink 在 Java 10 上启动时失败。TaskManager : java. lang.ClassCastException: [B 无法转换为 [C]