Last active
December 30, 2015 04:09
-
-
Save bryce-anderson/7774073 to your computer and use it in GitHub Desktop.
untested method for parsing a Process using a Process1 while keeping any remaining Process
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
def weave[O, B, F[_]](p: Process[F, O], p1: Process1[O, B]) | |
(implicit M: Monad[F], C: Catchable[F]): F[(Seq[B], Process[F, O])] = { | |
// Nearly a direct copy of process1.feed, except it returns any unused inputs | |
def feed(i: Seq[O], p: Process1[O,B]): (Seq[O], Process1[O,B]) = { | |
@annotation.tailrec | |
def go(in: Seq[O], out: Vector[Seq[B]], cur: Process1[O,B]): (Seq[O], Process1[O,B]) = | |
if (in.nonEmpty) cur match { | |
case h@Halt(_) => (in, emitSeq(out.flatten, h)) | |
case Emit(h, t) => go(in, out :+ h, t) | |
case Await1(recv, fb, c) => | |
val next = | |
try recv(in.head) | |
catch { | |
case End => fb | |
case e: Throwable => c.causedBy(e) | |
} | |
go(in.tail, out, next) | |
} | |
else (in, if (out.isEmpty) cur else emitSeq(out.flatten, cur)) | |
go(i, Vector(), p) | |
} | |
p match { | |
case Emit(seq, tail) => | |
if (seq.isEmpty) weave(tail.asInstanceOf[Process[F,O]], p1) | |
else { | |
val _t = feed(seq.asInstanceOf[Seq[O]], p1) | |
if (_t._1.isEmpty) weave(tail.asInstanceOf[Process[F,O]], _t._2) | |
// We got some unused input. The P1 *MUST* be done | |
else _t._2 match { | |
case h@Halt(End) => // The Process1 has ended with no output | |
M.point((Nil, Emit(seq.asInstanceOf[Seq[O]], tail.asInstanceOf[Process[F,O]]))) | |
case Halt(t) => C.fail(t) | |
case Emit(p1seq, Halt(End)) => // Got some output | |
M.point((p1seq, Emit(_t._1.asInstanceOf[Seq[O]], tail.asInstanceOf[Process[F,O]]))) | |
case Emit(p1seq, Halt(t)) => C.fail(t) | |
case _ => sys.error("Shouldn't get here!") | |
} | |
} | |
case Await(f, recv, fb, c) => | |
M.bind(C.attempt(f.asInstanceOf[F[AnyRef]]))( | |
_.fold( | |
{ case End => weave(fb.asInstanceOf[Process[F,O]], p1) | |
case e => weave(c.asInstanceOf[Process[F,O]].causedBy(e), p1) | |
}, | |
o => weave(recv.asInstanceOf[AnyRef => Process[F,O]](o), p1) | |
)) | |
case h@Halt(End) => M.point((p1.unemit._1, h)) | |
case Halt(t) => C.fail(t) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment