scala - 无法解析路径相关的类型类证据,而没有可访问的值类型

标签 scala implicit scalac path-dependent-type

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

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 方法使用现有类型,但我遇到了几个非常丑陋的问题和此类错误,使我的应用程序看起来像一个过度设计的废话......

最佳答案

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

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 ,所以它被认为是不稳定的。

关于scala - 无法解析路径相关的类型类证据,而没有可访问的值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27589770/

相关文章:

scala - Intellij 代码样式对齐单行注释

scala - 从伴生对象导入但未使用的隐式值

c - 即使添加了 #include <stdio.h> 也隐式声明了 popen

scala - 如何找到导致 Scalac 编译器崩溃的源文件

scala - 在 Scala 和 SBT 中调试较长的编译时间

scala - 如何在 List[F[G[A]]] 上运行序列以获得 F[G[List[A]]]

scala - "apply"在 Scala 的伴生对象(带有 Trait)中如何工作?

javascript - 使用 "Class"成员函数作为 setInterval() 的参数

scala - 将scala-compiler.jar添加为运行时依赖项

scala - 如何找到 Scala 编译器标志/选项的描述?