-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathPartial.scala
83 lines (71 loc) · 2.38 KB
/
Partial.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
object P extends Symantics {
val maxFixEvalDepth = 10
case class Repr[D,S](val c: C.Repr[D,D], val r: Option[R.Repr[S,S]]) {
override def toString = r match {
case Some(r) => s"Folded : $r"
case None => s"Partial: $c"
}
}
private def repr[D,S](c: C.Repr[D,D]) = Repr[D,S](c, None)
private def repr[D,S](c: C.Repr[D,D], r: R.Repr[S,S]) = Repr(c, Some(r))
def int(c: Int): Repr[Int,Int] = repr(C.int(c), R.int(c))
def bool(c: Boolean): Repr[Boolean,Boolean] = repr(C.bool(c), R.bool(c))
def lam[A, B](f: SFun[A,B]): RLam[A,B] = {
// need to ascribe here.
val crepr: C.Repr[A => B, A => B] =
C.lam((x: C.Repr[A,A]) => f(repr[A,A](x)).c)
repr(crepr, f)
}
def app[A, B](f: Repr[A => B, SFun[A,B]])(v: Repr[A,A]): Repr[B,B] = f.r match {
case Some(f) => f(v)
case None => repr(C.app(f.c)(v.c))
}
def _if[A,B](c: Repr[Boolean,Boolean])(t: =>Repr[A,B])(e: =>Repr[A,B]): Repr[A,B] = c.r match {
case Some(true) => t
case Some(false) => e
case None => repr(C._if(c.c)(t.c)(e.c))
}
def add(lhs: Repr[Int,Int], rhs: Repr[Int,Int]): Repr[Int,Int] = (lhs.r, rhs.r) match {
case (Some(v1), Some(v2)) =>
repr(C.int(v1 + v2), R.add(v1, v2))
case (Some(0), _) =>
repr(rhs.c)
case (_, Some(0)) =>
repr(lhs.c)
case _ => repr(C.add(lhs.c, rhs.c))
}
def mul(lhs: Repr[Int,Int], rhs: Repr[Int,Int]): Repr[Int,Int] = (lhs.r, rhs.r) match {
case (Some(v1), Some(v2)) =>
repr(C.int(v1 * v2), R.mul(v1, v2))
case (Some(0), _) | (_, Some(0)) =>
repr(C.int(0), R.int(0))
case (Some(1), _) =>
repr(rhs.c)
case (_, Some(1)) =>
repr(lhs.c)
case _ => repr(C.mul(lhs.c, rhs.c))
}
def leq(lhs: Repr[Int,Int], rhs: Repr[Int,Int]): Repr[Boolean,Boolean] = (lhs.r, rhs.r) match {
case (Some(v1), Some(v2)) =>
repr(C.bool(v1 <= v2), R.leq(v1, v2))
case _ =>
repr(C.leq(lhs.c, rhs.c))
}
def fix[A,B](f: (() => RLam[A,B]) => RLam[A,B]): RLam[A,B] = {
def self(d: Int): RLam[A,B] = {
if (d <= maxFixEvalDepth)
f(() => self(d+1))
else {
val cfix = C.fix[A,B] { cSelf =>
f(() => repr(cSelf())).c
}
repr(cfix)
}
}
self(0)
}
def eval[T](exp: Repr[T,T]): T = exp.r getOrElse { C.eval(exp.c) }
override def hole[D,S](exp: =>Repr[D,S]): Repr[D,S] = {
repr(C.hole(exp.c))
}
}