我正在研究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
没有任何意义。任何人都可以解释它是如何工作的?
答案 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