我正在玩type-level programming in scala:
import language.{higherKinds, postfixOps}
/**
* Created by kaiyin on 1/24/16.
*/
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
type FoldR[Init <: Type, Type, F <: RFold[Nat, Type]] <: Type
type FoldL[Init <: Type, Type, F <: LFold[Type, Nat]] <: Type
}
trait RFold[-Elem, Value] {
type Apply[E <: Elem, V <: Value] <: Value
}
trait LFold[Value, -Elem] {
type Apply[V <: Value, E <: Elem] <: Value
}
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
type FoldR[Init <: Type, Type, F <: RFold[Nat, Type]] = Init
type FoldL[Init <: Type, Type, F <: LFold[Type, Nat]] = Init
}
sealed trait Succ[N <: Nat] extends Nat {
type Match[NonZero[N <: Nat] <: Up, IfZero <: Up, Up] = NonZero[N]
// Here the parameter of N#Compare is the predecessor of O (when O has one)
type Compare[O <: Nat] = O#Match[N#Compare, GT, Comparison]
type FoldR[Init <: Type, Type, F <: RFold[Nat, Type]] = F#Apply[Succ[N], N#FoldR[Init, Type, F]]
type FoldL[Init <: Type, Type, F <: LFold[Type, Nat]] = N#FoldL[F#Apply[Init, Succ[N]], Type, F]
}
type Inc = RFold[Nat, Nat] {
type Apply[N <: Nat, Acc <: Nat] = Succ[Acc]
}
type Add[A <: Nat, B <: Nat] = A#FoldR[B, Nat, Inc]
type Sum[By <: Nat] = LFold[Nat, Nat] {
type Apply[Acc <: Nat, N <: Nat] = Add[By, Acc]
}
type Mult[A <: Nat, B <: Nat] = A#FoldL[_0, Nat, Sum[B]]
object Ints {
type _1 = Succ[_0]
type _2 = Succ[_1]
type _3 = Succ[_2]
type _4 = Succ[_3]
type _5 = Succ[_4]
type _6 = Succ[_5]
type _7 = Succ[_6]
type _8 = Succ[_7]
type _9 = Succ[_8]
type _10 = Succ[_9]
type _11 = Succ[_10]
type _12 = Succ[_11]
type _13 = Succ[_12]
type _14 = Succ[_13]
type _15 = Succ[_14]
type _16 = Succ[_15]
type _17 = Succ[_16]
type _18 = Succ[_17]
type _19 = Succ[_18]
type _20 = Succ[_19]
type _21 = Succ[_20]
type _22 = Succ[_21]
type _23 = Succ[_22]
type _24 = Succ[_23]
type _25 = Succ[_24]
type _26 = Succ[_25]
type _27 = Succ[_26]
type _28 = Succ[_27]
type _29 = Succ[_28]
type _30 = Succ[_29]
type _31 = Succ[_30]
type _32 = Succ[_31]
type _33 = Succ[_32]
type _34 = Succ[_33]
type _35 = Succ[_34]
type _36 = Succ[_35]
type _37 = Succ[_36]
type _38 = Succ[_37]
type _39 = Succ[_38]
type _40 = Succ[_39]
type _41 = Succ[_40]
type _42 = Succ[_41]
type _43 = Succ[_42]
type _44 = Succ[_43]
type _45 = Succ[_44]
type _46 = Succ[_45]
type _47 = Succ[_46]
type _48 = Succ[_47]
type _49 = Succ[_48]
type _50 = Succ[_49]
type _51 = Succ[_50]
type _52 = Succ[_51]
type _53 = Succ[_52]
type _54 = Succ[_53]
type _55 = Succ[_54]
type _56 = Succ[_55]
type _57 = Succ[_56]
type _58 = Succ[_57]
type _59 = Succ[_58]
type _60 = Succ[_59]
type _61 = Succ[_60]
type _62 = Succ[_61]
type _63 = Succ[_62]
type _64 = Succ[_63]
type _65 = Succ[_64]
type _66 = Succ[_65]
type _67 = Succ[_66]
type _68 = Succ[_67]
type _69 = Succ[_68]
type _70 = Succ[_69]
type _71 = Succ[_70]
type _72 = Succ[_71]
type _73 = Succ[_72]
type _74 = Succ[_73]
type _75 = Succ[_74]
type _76 = Succ[_75]
type _77 = Succ[_76]
type _78 = Succ[_77]
type _79 = Succ[_78]
type _80 = Succ[_79]
type _81 = Succ[_80]
type _82 = Succ[_81]
type _83 = Succ[_82]
type _84 = Succ[_83]
type _85 = Succ[_84]
type _86 = Succ[_85]
type _87 = Succ[_86]
type _88 = Succ[_87]
type _89 = Succ[_88]
type _90 = Succ[_89]
type _91 = Succ[_90]
type _92 = Succ[_91]
type _93 = Succ[_92]
type _94 = Succ[_93]
type _95 = Succ[_94]
type _96 = Succ[_95]
type _97 = Succ[_96]
type _98 = Succ[_97]
type _99 = Succ[_98]
type _100 = Succ[_99]
}
import Ints._
// for(i <- 5 to 100) {
// println(s"type _$i = Succ[_${i - 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
)
type C = _0#FoldR[Int, AnyVal, RFold[Nat, AnyVal]]
// compiles, because C is Int
implicitly[C =:= Int]
// Add 0 and 1
type x01 = Add[_0, _1]
type x02 = _0#FoldR[_1, Nat, Inc]
type x03 = _1
// Add 1 and 0
type x04 = Add[_1, _0]
type x05 = _1#FoldR[_0, Nat, Inc]
type x06 = Inc#Apply[_1, _0#FoldR[_0, Nat, Inc]]
type x07 = Inc#Apply[_1, _0]
type x08 = Succ[_0]
type x09 = _1
// Add 1 and 1
type x10 = Add[_1, _1]
type x11 = _1#FoldR[_1, Nat, Inc]
type x12 = Inc#Apply[_1, _0#FoldR[_1, Nat, Inc]]
type x13 = Inc#Apply[_1, _1]
type x14 = Succ[_1]
type x15 = _2
implicitly[x14 =:= _2]
// Add 3 and 1
type x16 = Add[_3, _1]
type x17 = _3#FoldR[_1, Nat, Inc]
type x18 = Inc#Apply[_3, _2#FoldR[_1, Nat, Inc]]
type x19 = Inc#Apply[_3, Inc#Apply[_2, _1#FoldR[_1, Nat, Inc]]]
type x20 = Inc#Apply[_3, Inc#Apply[_2, Inc#Apply[_1, _0#FoldR[_1, Nat, Inc]]]]
type x21 = Succ[Succ[Succ[_1]]]
type x22 = _4
// type Sum[By <: Nat] = LFold[Nat, Nat] {
// type Apply[Acc <: Nat, N <: Nat] = Add[By, Acc]
// }
// type Mult[A <: Nat, B <: Nat] = A#FoldL[_0, Nat, Sum[B]]
// 3 times 2
// type x23 = Mult[_3, _2]
type x24 = _3#FoldL[_0, Nat, Sum[_2]]
type x25 = _2#FoldL[Sum[_2]#Apply[_0, _3], Nat, Sum[_2]]
type x26 = _2#FoldL[_2, Nat, Sum[_2]]
type x27 = _1#FoldL[Sum[_2]#Apply[_2, _2], Nat, Sum[_2]]
type x28 = _1#FoldL[_4, Nat, Sum[_2]]
type x29 = _0#FoldL[Sum[_2]#Apply[_4, _1], Nat, Sum[_2]]
type x30 = Sum[_2]#Apply[_4, _1]
type x31 = _6
implicitly[x24 =:= _6]
}
}
这是类型级别的Peano算法的实现。所有工作都按预期工作,除非我取消注释这一行:
// type x23 = Mult[_3, _2]
我收到此错误:
Error:(272, 10) cyclic aliasing or subtyping involving type FoldL
type x23 = Mult[_3, _2]
^
知道出了什么问题吗?
我也不太明白为什么在这部分
trait RFold[-Elem, Value] {
type Apply[E <: Elem, V <: Value] <: Value
}
Elem
必须是逆变的。
使用FoldR
代替FoldL
无法解决问题。