Advertisement
Guest User

Untitled

a guest
May 24th, 2015
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.68 KB | None | 0 0
  1. sealed trait Nat { type N <: Nat }
  2. sealed trait S[P <: Nat] extends Nat { type N = S[P] }
  3. sealed trait Z extends Nat { type N = Z }
  4.  
  5. sealed trait Pred[A <: Nat] { type Out <: Nat }
  6. object Pred {
  7. def apply[A <: Nat](implicit pred: Pred[A]): Aux[A, pred.Out] = pred
  8. type Aux[A <: Nat, B <: Nat] = Pred[A] { type Out = B }
  9. implicit def pred[B <: Nat]: Aux[S[B], B] = new Pred[S[B]] { type Out = B }
  10. }
  11.  
  12. sealed trait LT[A <: Nat, B <: Nat]
  13. object LT {
  14. def apply[A <: Nat, B <: Nat](implicit lt: LT[A, B]): LT[A, B] = lt
  15.  
  16. implicit def lt1[B <: Nat] = new LT[Z, S[B]] { }
  17. implicit def lt2[A <: Nat, B <: Nat](implicit lt: LT[A, B]) =
  18. new LT[S[A], S[B]] { }
  19. }
  20.  
  21. sealed trait LTEQ[A <: Nat, B <: Nat]
  22. object LTEQ {
  23. def apply[A <: Nat, B <: Nat](implicit lteq: LTEQ[A, B]): LTEQ[A, B] = lteq
  24.  
  25. implicit def lteq1 = new LTEQ[Z, Z] { }
  26. implicit def lteq2[B <: Nat] = new LTEQ[Z, S[B]] { }
  27. implicit def lteq3[A <: Nat, B <: Nat](implicit lteq: LTEQ[A, B]) =
  28. new LTEQ[S[A], S[B]] { }
  29. }
  30.  
  31. sealed trait Max[A <: Nat, B <: Nat] { type Out <: Nat }
  32. object Max {
  33. def apply[A <: Nat, B <: Nat](implicit max: Max[A, B]): Aux[A, B, max.Out] = max
  34.  
  35. type Aux[A <: Nat, B <: Nat, C <: Nat] = Max[A, B] { type Out = C }
  36.  
  37. implicit def maxAux0[A <: Nat, B <: Nat]
  38. (implicit lteq: LTEQ[A, B]): Aux[A, B, B] = new Max[A, B] { type Out = B }
  39. implicit def maxAux1[A <: Nat, B <: Nat]
  40. (implicit lt: LT[B, A]): Aux[A, B, A] = new Max[A, B] { type Out = A }
  41. }
  42.  
  43. object NonRecursiveTrees {
  44. sealed trait Tree[+A]
  45. case class Leaf[+A](value: A) extends Tree[A]
  46. case class Node[+A](left: Tree[A], right: Tree[A]) extends Tree[A]
  47. type WithDepth[+A, B <: Nat] = A { type Depth = B }
  48.  
  49. def leaf[A](value: A): WithDepth[Leaf[A], Z] =
  50. new Leaf(value) { type Depth = Z }
  51. def node[A, L <: Nat, R <: Nat]
  52. (left: WithDepth[Tree[A], L], right: WithDepth[Tree[A], R])
  53. (implicit max: Max[L, R]): WithDepth[Node[A], S[max.Out]] =
  54. new Node(left, right) { type Depth = S[max.Out] }
  55.  
  56. implicit class TreeOps[A, DL <: Nat](val lhs: WithDepth[Tree[A], DL]) {
  57. def ~[B <: A, DR <: Nat](rhs: WithDepth[Tree[B], DR])
  58. (implicit max: Max[DL, DR]) = node[A, DL, DR](lhs, rhs)
  59. def ~[B <: A](rhs: B): WithDepth[Tree[A], S[DL]] =
  60. new Node(lhs, new Leaf(rhs)) { type Depth = S[DL] }
  61. }
  62. implicit class LeafOps[A](val lhs: A) {
  63. def ~[B <: A, D <: Nat]
  64. (rhs: WithDepth[Tree[B], D]): WithDepth[Tree[A], S[D]] =
  65. new Node(new Leaf(lhs), rhs) { type Depth = S[D] }
  66. def ~[B <: A](rhs: B): WithDepth[Tree[A], S[Z]] =
  67. new Node(new Leaf(lhs), new Leaf(rhs)) { type Depth = S[Z] }
  68. }
  69. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement