类型推断如何与递归隐式定义一起使用?

时间:2016-11-03 14:16:07

标签: scala type-inference implicit scalac

我正在尝试掌握以下文章:Typelevel quicksort in Scala

作者在一开始就介绍了类型级自然数:

sealed trait Nat
final class _0 extends Nat
final class Succ[P <: Nat]() extends Nat
trait Sum[A <: Nat, B <: Nat] { type Out <: Nat }

object Sum {
  def apply[A <: Nat, B <: Nat](implicit sum: Sum[A, B]): Aux[A, B, sum.Out] = sum

  type Aux[A <: Nat, B <: Nat, C <: Nat] = Sum[A, B] { type Out = C }

  implicit def sum1[B <: Nat]: Aux[_0, B, B] = new Sum[_0, B] { type Out = B }
  implicit def sum2[A <: Nat, B <: Nat]
    (implicit sum : Sum[A, Succ[B]]): Aux[Succ[A], B, sum.Out] = new Sum[Succ[A], B] { type Out = sum.Out }
}

它的工作方式如下:

scala> :t Sum[Succ[_0], Succ[Succ[_0]]]
Sum[Succ[_0],Succ[Succ[_0]]]{type Out = Succ[Succ[Succ[_0]]]}

以下是我在这种情况下“理解”编译器的工作原理。首先,编译器在伴随对象中找到apply方法:

Sum.apply[Succ[_0], Succ[Succ[_0]]](implicit sum: Sum[Succ[_0], Succ[Succ[_0]]]): 
        Aux[Succ[_0], Succ[Succ[_0]], sum.Out] = sum 

现在需要找到类型为sum的隐式参数Sum[Succ[_0], Succ[Succ[_0]]]。我了解正确的sum2 A = _0B = Succ[Succ[_0]]

但编译器如何做到这一点?它是否对输出类型执行某种模式匹配,以实现如果_0A它将获得正确的输出类型?最后是否存在这种模式匹配复杂程度的规则?

编辑:Where does Scala look for implicits?”的答案可以很好地解释编译器在何处以及优先级中寻找隐式定义。我的问题是关于类型推断机制。编译器如何在示例中表示Sum这样的递归类型?当它的某些部分未知时,它如何与隐式定义的输出类型相匹配?

0 个答案:

没有答案