Permalink
Browse files

checkpoint scala logic post 2

  • Loading branch information...
1 parent c43b8e7 commit 89cc2bc3a3c7f0eeb81579b22ecc27b65ff6f95e @jaked committed Apr 22, 2011
@@ -12,12 +12,15 @@ trait Logic { L =>
def or[A](as: List[A]): T[A] =
as.foldRight(fail[A])((a, t) => or(unit(a), t))
- def run[A](t: T[A], n: Int): List[A] =
- if (n <= 0) Nil else
- split(t) match {
- case None => Nil
- case Some((a, t)) => a :: run(t, n - 1)
- }
+ def run[A](t: T[A], n: Int): List[A] = {
+ def runAcc(t: T[A], n: Int, acc: List[A]): List[A] =
+ if (n <= 0) acc.reverse else
+ split(t) match {
+ case None => Nil
+ case Some((a, t)) => runAcc(t, n - 1, a :: acc)
+ }
+ runAcc(t, n, Nil)
+ }
case class Syntax[A](t: T[A]) {
def map[B](f: A => B): T[B] = L.apply(t, f)
@@ -98,10 +101,9 @@ object LogicSFK extends Logic {
}
}
-case object Fail extends Exception
-case object Finish extends Exception
-
object LogicSKE extends Logic {
+ case object Fail extends Exception
+
type T[A] = (A => Unit) => Unit
def fail[A] = { sk => throw Fail }
@@ -125,6 +127,8 @@ object LogicSKE extends Logic {
t(a => if (p(a)) sk(a) else throw Fail)
}
+ case object Finish extends Exception
+
def split[A](t: T[A]) = throw new Exception("unimplemented")
override def run[A](t: T[A], n: Int): List[A] = {
@@ -136,8 +140,71 @@ object LogicSKE extends Logic {
}
try {
t(sk)
- throw Finish // for the typechecker, not reached
+ throw new Exception("not reached")
}
catch { case Fail | Finish => lb.result }
}
}
+
+object LogicSKE2 extends Logic {
+ case object Fail extends Exception
+ class Succeed[A](val a: A, var s: List[() => Unit]) extends Exception
+
+ type T[A] = (A => Unit) => Unit
+
+ def fail[A] = { sk => throw Fail }
+
+ def unit[A](a: A) = { sk => sk(a) }
+
+ def or[A](t1: T[A], t2: => T[A]) =
+ { sk =>
+ try { t1(sk) }
+ catch {
+ case Fail => t2(sk)
+ case e: Succeed[_] => {
+ e.s = { () => t2(sk) } :: e.s
+ throw e
+ }
+ }
+ }
+
+ def bind[A,B](t: T[A], f: A => T[B]) =
+ { sk => t(a => f(a)(sk)) }
+
+ def apply[A,B](t: T[A], f: A => B) =
+ { sk => t(a => sk(f(a))) }
+
+ def filter[A](t: T[A], p: A => Boolean) =
+ { sk =>
+ t(a => if (p(a)) sk(a) else throw Fail)
+ }
+
+ def split[A](t: T[A]) = {
+ def restore(s: List[() => Unit]) {
+ s match {
+ case Nil => throw Fail
+ case cp :: s =>
+ try { restore(s) }
+ catch {
+ case Fail => cp()
+ case e: Succeed[_] => {
+ e.s = cp :: e.s
+ throw e
+ }
+ }
+ }
+ }
+ def unsplit[A](s: List[() => Unit]): T[A] =
+ try { restore(s); throw new Exception("not reached") }
+ catch {
+ case Fail => fail
+ case e: Succeed[A] => or(unit(e.a), bind(unit(e.s), unsplit))
+ }
+
+ try { t(a => throw new Succeed(a, Nil)); throw new Exception("not reached") }
+ catch {
+ case Fail => None
+ case e: Succeed[A] => Some((e.a, bind(unit(e.s), unsplit)))
+ }
+ }
+}
@@ -15,12 +15,15 @@ trait LogicState { L =>
def or[S,A](as: List[A]): T[S,A] =
as.foldRight(fail[S,A])((a, t) => or(unit(a), t))
- def run[S,A](s0: S, t: T[S,A], n: Int): List[(S,A)] =
- if (n <= 0) Nil else
- split(s0, t) match {
- case None => Nil
- case Some((s, a, t)) => (s, a) :: run(s0, t, n - 1)
- }
+ def run[S,A](s0: S, t: T[S,A], n: Int): List[(S,A)] = {
+ def runAcc(t: T[S,A], n: Int, acc: List[(S,A)]): List[(S,A)] =
+ if (n <= 0) acc.reverse else
+ split(s0, t) match {
+ case None => Nil
+ case Some((s, a, t)) => runAcc(t, n - 1, (s, a) :: acc)
+ }
+ runAcc(t, n, Nil)
+ }
case class Syntax[S,A](t: T[S,A]) {
def map[B](f: A => B): T[S,B] = L.apply(t, f)
@@ -36,71 +39,67 @@ trait LogicState { L =>
}
object LogicStateSFK extends LogicState {
- // type FK[R] = => R
- type SK[S,A,R] = (S, A, => R) => R
+ type FK[R] = () => R
+ type SK[S,A,R] = (S, A, FK[R]) => R
- trait T[S,A] { def apply[R](s: S, sk: SK[S,A,R], fk: => R): R }
+ trait T[S,A] { def apply[R](s: S, sk: SK[S,A,R], fk: FK[R]): R }
def fail[S,A] =
new T[S,A] {
- def apply[R](s: S, sk: SK[S,A,R], fk: => R) = fk
+ def apply[R](s: S, sk: SK[S,A,R], fk: FK[R]) = fk()
}
def unit[S,A](a: A) =
new T[S,A] {
- def apply[R](s: S, sk: SK[S,A,R], fk: => R) = sk(s, a, fk)
+ def apply[R](s: S, sk: SK[S,A,R], fk: FK[R]) = sk(s, a, fk)
}
def or[S,A](t1: T[S,A], t2: => T[S,A]) =
new T[S,A] {
- def apply[R](s: S, sk: SK[S,A,R], fk: => R) = t1(s, sk, t2(s, sk, fk))
+ def apply[R](s: S, sk: SK[S,A,R], fk: FK[R]) = t1(s, sk, { () => t2(s, sk, fk) })
}
def bind[S,A,B](t: T[S,A], f: A => T[S,B]) =
new T[S,B] {
- def apply[R](s: S, sk: SK[S,B,R], fk: => R) =
+ def apply[R](s: S, sk: SK[S,B,R], fk: FK[R]) =
t(s, ({ (s, a, fk) => f(a)(s, sk, fk) }: SK[S,A,R]), fk)
}
def apply[S,A,B](t: T[S,A], f: A => B) =
new T[S,B] {
- def apply[R](s: S, sk: SK[S,B,R], fk: => R) =
+ def apply[R](s: S, sk: SK[S,B,R], fk: FK[R]) =
t(s, ({ (s, a, fk) => sk(s, f(a), fk) }: SK[S,A,R]), fk)
}
def filter[S,A](t: T[S,A], p: A => Boolean) =
new T[S,A] {
- def apply[R](s: S, sk: SK[S,A,R], fk: => R) =
- t(s, ({ (s, a, fk) => if (p(a)) sk(s, a, fk) else fk }: SK[S,A,R]), fk)
+ def apply[R](s: S, sk: SK[S,A,R], fk: FK[R]) =
+ t(s, ({ (s, a, fk) => if (p(a)) sk(s, a, fk) else fk() }: SK[S,A,R]), fk)
}
def split[S,A](s: S, t: T[S,A]) = {
def stateUnit[S,A](s: S, a: A): T[S,A] =
new T[S,A] {
- def apply[R](s: S, sk: SK[S,A,R], fk: => R) = sk(s, a, fk)
+ def apply[R](s: S, sk: SK[S,A,R], fk: FK[R]) = sk(s, a, fk)
}
- def unsplit(r: Option[(S,A,T[S,A])]): T[S,A] =
- r match {
+ def unsplit(r: () => Option[(S,A,T[S,A])]): T[S,A] =
+ r() match {
case None => fail
case Some((s, a, t)) => or(stateUnit(s, a), t)
}
- def byNameUnit[S,A](a: => A): T[S,A] =
- new T[S,A] {
- def apply[R](s: S, sk: SK[S,A,R], fk: => R) = sk(s, a, fk)
- }
def sk : SK[S,A,Option[(S,A,T[S,A])]] =
- { (s, a, fk) => Some(s, a, byNameUnit(fk).flatMap(unsplit)) }
- t(s, sk, None)
+ { (s, a, fk) => Some((s, a, unit(fk).flatMap(unsplit))) }
+ t(s, sk, { () => None })
}
def get[S]: T[S,S] =
new T[S,S] {
- def apply[R](s: S, sk: SK[S,S,R], fk: => R) = sk(s, s, fk)
+ def apply[R](s: S, sk: SK[S,S,R], fk: FK[R]) = sk(s, s, fk)
}
def set[S](s: S): T[S,Unit] =
new T[S,Unit] {
- def apply[R](_s: S, sk: SK[S,Unit,R], fk: => R) = sk(s, (), fk)
+ def apply[R](_s: S, sk: SK[S,Unit,R], fk: FK[R]) = sk(s, (), fk)
}
}
@@ -139,7 +138,7 @@ object LogicStateSKE extends LogicState {
}
try {
t(s, sk)
- throw Finish // for the typechecker, not reached
+ throw new Exception("not reached")
}
catch { case Fail | Finish => lb.result }
}
Oops, something went wrong.

0 comments on commit 89cc2bc

Please sign in to comment.