【问题标题】:Type inferred to Nothing in Scala在 Scala 中类型推断为 Nothing
【发布时间】:2011-10-16 19:38:21
【问题描述】:

当我尝试编译这个小例子时:

trait Foo[A,B] {
  type F[_,_]
  def foo(): F[A,B]
}

class Bar[A,B] extends Foo[A,B] {
  type F[D,E] = Bar[D,E]
  def foo() = this
}

object Helper {
  def callFoo[A,B,FF <: Foo[A,B]]( f: FF ): FF#F[A,B] =
    f.foo()
}

object Run extends App {
  val x = new Bar[Int,Double]
  val y = Helper.callFoo(x)
  println( y.getClass )
}

我得到错误:

[error] src/Issue.scala:20: inferred type arguments
[Nothing,Nothing,issue.Bar[Int,Double]] do not conform to method callFoo's type
parameter bounds [A,B,FF <: issue.Foo[A,B]]
[error]       val y = Helper.callFoo(x)

显然,类型推断机制无法从 Bar[A,B] 推断出 A 和 B。但是,如果我手动传递所有类型,它就可以工作:

val y = Helper.callFoo[Int,Double,Bar[Int,Double]](x)

我有办法避免显式传递类型吗?

【问题讨论】:

    标签: scala types type-inference


    【解决方案1】:

    您必须将callFoo 的签名更改为:

    def callFoo[A, B, FF[A, B] <: Foo[A, B]](f: FF[A, B]): FF[A, B]#F[A, B] =
    

    你必须告诉编译器FF实际上是一个参数化类型。

    【讨论】:

    • @Kipton_Barros:嗯,我选择 Jean-Phillipe 的答案只是因为它意味着对我当前的代码库进行更少的重构。
    • @paradigmatic 是的,Jean-Philippe 的回答非常好。我发现有趣的是,尽管FF 参数不必是更高种类的,但使它如此有助于推理。我在一个相关问题上尝试了 Jean-Philippe 的技术,但到目前为止无法让它发挥作用:stackoverflow.com/questions/6892781/…
    【解决方案2】:

    使用类型members代替参数行吗?

    trait Foo {
      type A
      type B
      type F
      def foo(): F
    }
    
    class Bar extends Foo {
      type F = Bar
      def foo() = this
    }
    
    object Helper {
      def callFoo[FF <: Foo]( f: FF ): FF#F =
        f.foo()
    }
    
    object Run extends App {
      val x = new Bar{type A=Int; type B=Double}
      val y = Helper.callFoo(x)
      println( y.getClass )
    }
    

    当使用类型成员时,知道它们可以通过细化作为类型参数出现是很有用的,正如 Miles Sabin 对Why is this cyclic reference with a type projection illegal? 的回答中所述:

    另请参阅这个最近的问题,它与您的问题相似:Scala fails to infer the right type arguments

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      • 1970-01-01
      • 1970-01-01
      • 2012-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多