Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
much more straightforward apply loop
- Loading branch information
Jake Donham
committed
May 12, 2011
1 parent
ba9621f
commit a976a52
Showing
1 changed file
with
59 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,91 +1,75 @@ | ||
object LogicSFKDefuncTailrec extends Logic { | ||
type O[A] = Option[(A,T[A])] | ||
|
||
sealed trait T[A] | ||
case class Fail[A]() extends T[A] | ||
case class Unit[A](a: A) extends T[A] | ||
case class Or[A](t1: T[A], t2: () => T[A]) extends T[A] | ||
case class Bind[A,B](t: T[A], f: A => T[B]) extends T[B] | ||
case class Apply[A,B](t: T[A], f: A => B) extends T[B] | ||
case class Filter[A](t: T[A], p: A => Boolean) extends T[A] | ||
case class Unsplit[A](fk: FK) extends T[A] | ||
type T[A] = I | ||
|
||
sealed trait FK | ||
case class FKOr(t: () => T[Any], sk: SK, fk: FK) extends FK | ||
case class FKSplit(r: O[Any]) extends FK | ||
sealed trait I | ||
case class Fail() extends I | ||
case class Unit(a: Any) extends I | ||
case class Or(t1: I, t2: () => I) extends I | ||
case class Bind(t: I, f: Any => I) extends I | ||
case class Apply(t: I, f: Any => Any) extends I | ||
case class Filter(t: I, p: Any => Boolean) extends I | ||
case class Unsplit(fk: I) extends I | ||
|
||
sealed trait SK | ||
case class SKBind(f: Any => T[Any], sk: SK) extends SK | ||
case class SKApply(f: Any => Any, sk: SK) extends SK | ||
case class SKFilter(p: Any => Boolean, sk: SK) extends SK | ||
case class SKSplit(r: (Any, FK) => O[Any]) extends SK | ||
case class FKOr(t: () => I, sk: I, fk: I) extends I | ||
case class FKSplit(r: O[Any]) extends I | ||
|
||
sealed trait K | ||
case object KReturn extends K | ||
case class KUnsplit(sk: SK, fk: FK, k: K) extends K | ||
case class SKBind(f: Any => I, sk: I) extends I | ||
case class SKApply(f: Any => Any, sk: I) extends I | ||
case class SKFilter(p: Any => Boolean, sk: I) extends I | ||
case class SKSplit(r: (Any, I) => O[Any]) extends I | ||
|
||
def fail[A] = Fail() | ||
def unit[A](a: A) = Unit(a) | ||
def or[A](t1: T[A], t2: => T[A]) = Or(t1, { () => t2 }) | ||
def bind[A,B](t: T[A], f: A => T[B]) = Bind(t, f) | ||
def apply[A,B](t: T[A], f: A => B) = Apply(t, f) | ||
def filter[A](t: T[A], p: A => Boolean) = Filter(t, p) | ||
case object KReturn extends I | ||
case class KUnsplit(sk: I, fk: I, k: I) extends I | ||
|
||
def split[A](t2: T[A]): O[A] = { | ||
var app = 0 | ||
var t = t2.asInstanceOf[T[Any]] | ||
var a: Any = null | ||
var r: O[Any] = null | ||
var sk: SK = SKSplit((a, fk) => Some((a, Unsplit(fk)))) | ||
var fk: FK = FKSplit(None) | ||
var k: K = KReturn | ||
def fail[A]: T[A] = Fail() | ||
def unit[A](a: A): T[A] = Unit(a) | ||
def or[A](t1: T[A], t2: => T[A]): T[A] = Or(t1, { () => t2 }) | ||
def bind[A,B](t: T[A], f: A => T[B]): T[B] = | ||
Bind(t, f.asInstanceOf[Any => I]) | ||
def apply[A,B](t: T[A], f: A => B): T[B] = | ||
Apply(t, f.asInstanceOf[Any => I]) | ||
def filter[A](t: T[A], p: A => Boolean): T[A] = | ||
Filter(t, p.asInstanceOf[Any => Boolean]) | ||
|
||
while (true) { | ||
app match { | ||
case 0 => // applyT | ||
t match { | ||
case Fail() => app = 1 | ||
case Unit(a2) => { a = a2; app = 2 } | ||
case Or(t1, t2) => { t = t1; fk = FKOr(t2, sk, fk) } | ||
case Bind(t2, f) => { t = t2; sk = SKBind(f, sk) } | ||
case Apply(t2, f) => { t = t2; sk = SKApply(f, sk) } | ||
case Filter(t2, p) => { t = t2; sk = SKFilter(p, sk) } | ||
case Unsplit(fk2) => { | ||
app = 1; k = KUnsplit(sk, fk, k); fk = fk2 | ||
} | ||
} | ||
def split[A](t: T[A]): O[A] = { | ||
def apply(i: I, a: Any, r: O[Any], sk: I, fk: I, k: I): O[Any] = | ||
i match { | ||
case Fail() => apply(fk, null, null, null, null, k) | ||
case Unit(a) => apply(sk, a, null, null, fk, k) | ||
case Or(t1, t2) => apply(t1, null, null, sk, FKOr(t2, sk, fk), k) | ||
case Bind(t, f) => apply(t, null, null, SKBind(f, sk), fk, k) | ||
case Apply(t, f) => apply(t, null, null, SKApply(f, sk), fk, k) | ||
case Filter(t, p) => apply(t, null, null, SKFilter(p, sk), fk, k) | ||
case Unsplit(fk2) => apply(fk2, null, null, null, null, KUnsplit(sk, fk, k)) | ||
|
||
case 1 => // applyFK | ||
fk match { | ||
case FKOr(t2, sk2, fk2) => { | ||
app = 0; t = t2(); sk = sk2; fk = fk2 | ||
} | ||
case FKSplit(r2) => { app = 3; r = r2 } | ||
} | ||
case FKOr(t, sk, fk) => apply(t(), null, null, sk, fk, k) | ||
case FKSplit(r) => apply(k, null, r, null, null, null) | ||
|
||
case 2 => // applySK | ||
sk match { | ||
case SKBind(f, sk2) => { app = 0; t = f(a); sk = sk2 } | ||
case SKApply(f, sk2) => { sk = sk2; a = f(a) } | ||
case SKFilter(p, sk2) => | ||
if (p(a)) sk = sk2 else app = 1 | ||
case SKSplit(rf) => { app = 3; r = rf(a, fk) } | ||
} | ||
case SKBind(f, sk) => apply(f(a), null, null, sk, fk, k) | ||
case SKApply(f, sk) => apply(sk, f(a), null, null, fk, k) | ||
case SKFilter(p, sk) => | ||
if (p(a)) | ||
apply(sk, a, null, null, fk, k) | ||
else | ||
apply(fk, null, null, null, null, k) | ||
case SKSplit(rf) => apply(k, null, rf(a, fk), null, null, null) | ||
|
||
case 3 => // applyK | ||
k match { | ||
case KReturn => return r.asInstanceOf[O[A]] | ||
case KUnsplit(sk2, fk2, k2) => | ||
r match { | ||
case None => { app = 1; fk = fk2; k = k2 } | ||
case Some((a2, t2)) => { | ||
app = 0; t = or(unit(a2), t2); sk = sk2 | ||
fk = fk2; k = k2 | ||
} | ||
} | ||
case KReturn => r | ||
case KUnsplit(sk, fk, k) => { | ||
r match { | ||
case None => apply(fk, null, null, null, null, k) | ||
case Some((a, t)) => apply(or(unit(a), t), null, null, sk, fk, k) | ||
} | ||
} | ||
} | ||
} | ||
throw new Exception("not reached") | ||
|
||
apply(t, | ||
null, | ||
null, | ||
SKSplit((a, fk) => Some((a, Unsplit(fk)))), | ||
FKSplit(None), | ||
KReturn).asInstanceOf[O[A]] | ||
} | ||
} |