为什么在这里传递不带参数的比较类型是可以的?

时间:2016-01-24 20:56:29

标签: scala type-level-computation

我正在研究scala中类型级编程的代码示例:

object TypeLevel {

  sealed trait True extends Bool {
    type If[T <: Up, F <: Up, Up] = T
  }

  sealed trait False extends Bool {
    type If[T <: Up, F <: Up, Up] = F
  }

  sealed trait Bool {
    type If[T <: Up, F <: Up, Up] <: Up
  }

  object Bool {
    type &&[A <: Bool, B <: Bool] = A#If[B, False, Bool]
    type ||[A <: Bool, B <: Bool] = A#If[True, B, Bool]
    type Not[A <: Bool] = A#If[False, True, Bool]
  }

  case class BoolRep[B <: Bool](val value: Boolean)

  def toBoolean[B <: Bool](implicit b: BoolRep[B]) = b.value

  implicit val falseRep: BoolRep[False] = BoolRep[False](false)
  implicit val trueRep: BoolRep[True] = BoolRep[True](true)

  sealed trait Comparison {
    type Match[IfLT <: Up, IfEQ <: Up, IfGT <: Up, Up] <: Up
    type gt = Match[False, False, True, Bool]
    type lt = Match[True, False, False, Bool]
    type eq = Match[False, True, False, Bool]
    type le = Match[True, True, False, Bool]
    type ge = Match[False, True, True, Bool]
  }

  sealed trait GT extends Comparison {
    type Match[IfLT <: Up, IfEQ <: Up, IfGT <: Up, Up] = IfGT
  }

  sealed trait LT extends Comparison {
    type Match[IfLT <: Up, IfEQ <: Up, IfGT <: Up, Up] = IfLT
  }

  sealed trait EQ extends Comparison {
    type Match[IfLT <: Up, IfEQ <: Up, IfGT <: Up, Up] = IfEQ
  }

  sealed trait Nat {
    type Match[NonZero[N <: Nat] <: Up, IfZero <: Up, Up] <: Up

    type Compare[N <: Nat] <: Comparison
  }

  sealed trait _0 extends Nat {
    type Match[NonZero[N <: Nat] <: Up, IfZero <: Up, Up] = IfZero

    type Compare[N <: Nat] =
    N#Match[ConstLT, EQ, Comparison]

    type ConstLT[A] = LT
  }

  sealed trait Succ[N <: Nat] extends Nat {
    type Match[NonZero[N <: Nat] <: Up, IfZero <: Up, Up] = NonZero[N]

    type Compare[O <: Nat] = O#Match[N#Compare, GT, Comparison]
  }

  type _1 = Succ[_0]
  type _2 = Succ[_1]
  type _3 = Succ[_2]
  type _4 = Succ[_1]

  type Is0[A <: Nat] = A#Match[ConstFalse, True, Bool]
  type ConstFalse[A] = False
  type ConstTrue[A] = True

  def printAll(strings: String*): Unit = {
    println(strings.mkString("\n"))
  }

  def main(args: Array[String]) {
    import Bool.{&&, ||, Not}
    printAll(
      toBoolean[True && False || Not[False]].toString,
      toBoolean[Is0[_0]].toString,
      toBoolean[_0#Compare[_0]#eq].toString,
      toBoolean[_1#Compare[_0]#gt] toString,
      toBoolean[_0#Compare[_1]#lt] toString,
      toBoolean[_1#Compare[_2]#lt] toString
    )
  }
}

这基本上允许您在编译时比较自然数。我可以追踪_1#Compare[_2]#lt的工作原理:

  • Succ[_0]#Compare[_2]#lt
  • _2#Match[_0#Compare, GT, Comparison]#lt

我迷失了。 Compare_0的签名是

type Compare[N <: Nat] = N#Match[ConstLT, EQ, Comparison]

因此它需要一个参数,并且此类型的定义依赖于该参数N_0#Compare没有任何意义。任何人都可以解释它是如何工作的?

1 个答案:

答案 0 :(得分:0)

我明白了:

time

_1#Compare[_2]#lt

Succ[_0]#Compare[_2]#lt

_2#Match[_0#Compare, GT, Comparison]#lt ......... Succ[_1]#Match[_0#Compare[_1], GT, Comparison]#lt中的_1被推断出来。

_0#Compare[_1]

_0#Compare[_1]#lt

LT#lt