无法解析路径依赖类型类证据,但值类型可访问



我被困了大约一个小时才发现这个事实:

class Foo {
  trait TypeClass[X]
  object TypeClass {
    implicit val gimme = new TypeClass[Int]{}
  }
  def foo[X : TypeClass](p: X): Unit = println("yeah " + p)
}
    // compiles
val foo = new Foo()
foo.foo(4)
    //does not compile
new Foo().foo(4)
    could not find implicit value for evidence parameter of type _1.TypeClass[Int]
    [error]   new Foo().foo(4)
    [error]    

我不知道为什么会这样。我唯一能想到的是,scalac 不会在没有任何前缀可访问的值类型中找到隐式。它不能被引用。Scalac 显然需要访问该Foo.this.foo来解决其中的隐式问题,而在这种情况下它不能。

我觉得如果你将类型类和路径依赖类型结合起来,你实际上是注定要失败的。你最终会处理这种事情。我这样做是因为 scalac 不会在我的 API 方法中推断类型,用户必须显式声明它们。所以我选择了这种设计,以便类型是用Foo[T]构造的,API 方法使用现有类型,但我遇到了几个非常丑陋的问题和此类错误,使我的应用程序看起来像一个过度设计的废话......

路径依赖类型可能只绑定到一些稳定的不可变值,所以更明显的例子也行不通,因为不可变性是不能保证的:

scala> var foo = new Foo()
foo: Foo = Foo@4bc814ba
scala> foo.foo(4)
<console>:17: error: could not find implicit value for evidence parameter of type    _37.TypeClass[Int]
          foo.foo(4)
                 ^
scala> def foo = new Foo()
foo: Foo
scala> foo.foo(4)
<console>:17: error: could not find implicit value for evidence parameter of type _39.TypeClass[Int]
          foo.foo(4)
                 ^

_37表示未推断出类型。所以,似乎 scala 只是在分配给某个val之后才推断类型。它实际上与隐式无关,这会给你更清晰的解释:

scala> class C {type K = Int}
defined class C
scala> var z = new C
z: C = C@4d151931
scala> def aaa(a: z.K) = a
<console>:16: error: stable identifier required, but z found.
   def aaa(a: z.K) = a
              ^
scala> def z = new C
z: C
scala> def aaa(a: z.K) = a
<console>:16: error: stable identifier required, but z found.
   def aaa(a: z.K) = a
              ^

您的new Foo表达式类似于def newFoo = new Foo,因此它被认为是不稳定的。

相关内容

  • 没有找到相关文章

最新更新