Scala 中依赖类型的隐式解析
Implicit resolution of dependent types in Scala
考虑以下代码:
trait Foo {
type T
def value: T
}
object Foo {
def apply[A](v: A): Foo = new Foo {
override type T = A
override def value = v
}
}
trait Decode[A] {
def apply(x: A): String
}
object Decode {
def apply[A](f: A => String): Decode[A] = new Decode[A] {
override def apply(x: A) = f(x)
}
implicit val decodeStr: Decode[String] = Decode(identity)
}
class Sandbox {
def decodeFoo(foo: Foo)(implicit decoder: Decode[foo.T]): String =
decoder(foo.value)
val foo = Foo("hello")
println(decodeFoo(foo))
}
上面的代码应该可以正常工作并打印 hello
但编译失败:
could not find implicit value for parameter decoder: Decode[Sandbox.this.foo.T]
[error] println(decodeFoo(foo))
即使我显式传入隐式参数:
println(decodeFoo(foo = foo)(decoder = Decode.decodeStr))
我现在仍然遇到这个错误:
type mismatch;
[error] found : Decode[String]
[error] required: Decode[Sandbox.this.foo.T]
[error] println(decodeFoo(foo = foo)(decoder = Decode.decodeStr))
[error] ^
当然,我可以使 Foo
成为 Foo[T]
并为其定义解码器,但这不是这个问题的重点 - 我想了解为什么上面的代码无法编译。
这里存在问题:
object Foo {
def apply[A](v: A): Foo = new Foo {
override type T = A
override def value = v
}
}
在那里,您已经确定您将 return 一个 Foo
但不是,具体来说, Foo
。因此,该函数只知道它可以 return 一个 Foo
用于任何类型 T
。您需要一个 Aux
模式来重新捕获在建立新的 Foo
时丢失的类型(是的,是的...)
object Foo {
type Aux[A] = Foo{ type T = A }
def apply[A](v: A): Aux[A] = new Foo {
type T = A
def value = v
}
}
然后说对于给定的 A
生成 Foo
其 T
依赖类型设置为 A
.
考虑以下代码:
trait Foo {
type T
def value: T
}
object Foo {
def apply[A](v: A): Foo = new Foo {
override type T = A
override def value = v
}
}
trait Decode[A] {
def apply(x: A): String
}
object Decode {
def apply[A](f: A => String): Decode[A] = new Decode[A] {
override def apply(x: A) = f(x)
}
implicit val decodeStr: Decode[String] = Decode(identity)
}
class Sandbox {
def decodeFoo(foo: Foo)(implicit decoder: Decode[foo.T]): String =
decoder(foo.value)
val foo = Foo("hello")
println(decodeFoo(foo))
}
上面的代码应该可以正常工作并打印 hello
但编译失败:
could not find implicit value for parameter decoder: Decode[Sandbox.this.foo.T]
[error] println(decodeFoo(foo))
即使我显式传入隐式参数:
println(decodeFoo(foo = foo)(decoder = Decode.decodeStr))
我现在仍然遇到这个错误:
type mismatch;
[error] found : Decode[String]
[error] required: Decode[Sandbox.this.foo.T]
[error] println(decodeFoo(foo = foo)(decoder = Decode.decodeStr))
[error] ^
当然,我可以使 Foo
成为 Foo[T]
并为其定义解码器,但这不是这个问题的重点 - 我想了解为什么上面的代码无法编译。
这里存在问题:
object Foo {
def apply[A](v: A): Foo = new Foo {
override type T = A
override def value = v
}
}
在那里,您已经确定您将 return 一个 Foo
但不是,具体来说, Foo
。因此,该函数只知道它可以 return 一个 Foo
用于任何类型 T
。您需要一个 Aux
模式来重新捕获在建立新的 Foo
时丢失的类型(是的,是的...)
object Foo {
type Aux[A] = Foo{ type T = A }
def apply[A](v: A): Aux[A] = new Foo {
type T = A
def value = v
}
}
然后说对于给定的 A
生成 Foo
其 T
依赖类型设置为 A
.