package rickyclarkson.sconditions trait Condition trait Error extends Condition case class MalformedLogEntryError(text: String) extends Error object Conditions { def error[T](e: Error)(implicit handler: Handler): T=handler handle e def handlerCase[T](matcher: Condition => Option[T])(expression: Handler => T)(implicit superHandler: Handler): T= { case class Break(c: Condition) extends Exception val handler=new Handler { def handle[T](c: Condition)=throw Break(c) } try { expression(handler) } catch { case Break(c) => matcher(c) match { case Some(t) => t case None => superHandler handle c } } } } trait Handler { def handle[T](c: Condition): T; } object Demo extends Application { case class LogEntry(val text: String) import Conditions.{error,handlerCase} def parseLogEntry(text: String)(implicit handler: Handler): LogEntry= { if (text startsWith "LOG") LogEntry(text) else error(MalformedLogEntryError(text)) } implicit val lastHandler=new Handler { def handle[T](c: Condition): T={ println(c) System exit 1 throw null }} println(handlerCase(c => Some("ah, damn it.. "+c+" happened")) { parseLogEntry("bye")(_).text }) println(for { entry <- List("LOG entry","invalid","LOG entries galore") parsed=handlerCase(c => Some("")) { parseLogEntry(entry)(_).text } if parsed!="" } yield entry ) println(parseLogEntry("hello")) }