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]                                                 ^

当然,我可以为其创建FooaFoo[T]并定义解码器,但这不是这个问题的重点-我想了解为什么上面的代码无法编译。

小麦味

这里存在问题:

object Foo {
  def apply[A](v: A): Foo = new Foo {
    override type T = A
    override def value = v
  }
}

在这里,您已经确定要返回一个(Foo但不具体返回)which Foo因此,该函数仅知道可以Foo为任何type返回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产品,FooT依赖类型设置为A

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章