pat*_*rit 4 scala implicit typeclass dependent-type scala-implicits
考虑以下代码:
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
  }
}
在那里,你已经确定你将返回一个,Foo但不是,特别是,哪个Foo.因此,该函数只知道它可以返回Foo任何类型的a 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.
| 归档时间: | 
 | 
| 查看次数: | 153 次 | 
| 最近记录: |