> What I really want to write is something like this:
>
> val ret = for[abortEarly] {
> as = xs map (_+1)
>
> _ = if (debug) println("debug2")
>
> bs = as map (_+1)
>
> cs = bs map (_+1)
> } yield ab ++ cs
Aleksey's solution won't give you this, because you want to have access to all of the variables you've bound in your for-comprehension (in order to compute as ++ cs at the end, for instance), which means the data you're passing around is not just one type. Try this; I think it has the properties you want:
val ret = (for {
_ <- new Abortable(abort).start
as = xs map (_+1)
_ = if (debug) println("debug2")
bs = as map (_+1)
cs = bs map (_+1)
} yield as ++ cs) getOrElse Nil
class Abortable(shouldAbort: => Boolean) {
trait OpList[A] {
def fold[Z](z: => Z)(f: A => Z): Z
}
class OpNil[A](value: A) extends OpList[A] {
def fold[Z](z: => Z)(f: A => Z) = f(value)
}
class OpCons[A, B](op: A => B, tail: OpList[A]) extends OpList[B] {
def fold[Z](z: => Z)(f: B => Z) = tail.fold(z) { a =>
if (shouldAbort) z else f(op(a))
}
}
class Computation[A](opList: OpList[A]) {
def map[B](op: A => B): Computation[B] = new Computation(new OpCons(op, opList))
def getOrElse(orElse: => A): A = opList.fold(orElse)(identity)
}
lazy val start: Computation[Unit] = new Computation(new OpNil(()))
}
(please forgive me my corporate legal disclaimer)
----------------------------------------
This message is intended exclusively for the individual(s) or entity to
which it is addressed. It may contain information that is proprietary,
privileged or confidential or otherwise legally exempt from disclosure.
If you are not the named addressee, you are not authorized to read,
print, retain, copy or disseminate this message or any part of it.
If you have received this message in error, please notify the sender
immediately by e-mail and delete all copies of the message.