涉及FoldL类型的循环别名或子类型

时间:2016-01-25 15:13:23

标签: scala type-level-computation

我正在玩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无法解决问题。

0 个答案:

没有答案