Last active
August 29, 2015 14:09
-
-
Save shajra/39cdc9c08546d334029a to your computer and use it in GitHub Desktop.
an idea for error handling in scalaz-stream
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
package myorg.extn.scalaz | |
import scala.Unit | |
import scalaz.{ \/, EitherT, Functor, Maybe } | |
import scalaz.EitherT.eitherT | |
import scalaz.stream.{ Process, Cause } | |
import scalaz.stream.Process. | |
{ emit, emitO, emitW, eval, eval_, fail, halt, repeatEval } | |
import scalaz.syntax.bind._ | |
/** Extension of Scalaz-stream library */ | |
package object stream { | |
object io { | |
def resource[F[_] : Functor, R, O] | |
(acquire: F[R]) | |
(release: R => F[Unit]) | |
(step: R => F[Maybe[O]]) | |
: Process[F,O] = { | |
type P[A] = Process[F, A] | |
val getResource: P[R] = eval(acquire) | |
def repeat(r: R): P[O] = | |
repeatEval(step(r)) >>= { _.map[P[O]](emit) | end[F, O] } | |
def repeatAndClose(r: R): P[O] = | |
repeat(r).onComplete[F, O](eval_(release(r))) | |
getResource >>= repeatAndClose | |
} | |
def resourceE[F[_] : Functor, R, E, O] | |
(acquire: F[E \/ R]) | |
(release: R => F[Unit]) | |
(step: R => F[Result[E, O]]) | |
: Process[F, E \/ O] = { | |
type P[A] = Process[F, A] | |
type EP[A] = EitherT[P, E, A] | |
val getResource: EP[R] = | |
eitherT[P, E, R](eval(acquire)) | |
def repeat(r: R): P[E \/ O] = | |
repeatEval(step(r)) >>= | |
{ res => | |
res fold[P[E \/ O]] ( | |
cont = emitO(_), | |
done = end[F, E \/ O], | |
failCont = emitW(_), | |
failStop = emitW(_) ++ (end[F, E \/ O])) | |
} | |
def repeatAndClose(r: R): EP[O] = | |
eitherT[P, E, O](repeat(r).onComplete[F, E \/ O](eval_(release(r)))) | |
getResource >>= repeatAndClose run | |
} | |
private def end[F[_], A]: Process[F, A] = { | |
//halt // this doesn't work | |
fail(Cause.Terminated(Cause.End)) // this works, but why? | |
} | |
} | |
} |
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
package myorg.extn.scalaz.stream | |
sealed abstract class Result[E, O] { | |
def fold[A] | |
(cont: O => A, done: => A, failCont: E => A, failStop: E => A) = | |
this match { | |
case Cont(o) => cont(o) | |
case Done() => done | |
case FailCont(e) => failCont(e) | |
case FailStop(e) => failStop(e) | |
} | |
} | |
private case class Cont[E, O](o: O) extends Result[E, O] | |
private case class Done[E, O]() extends Result[E, O] | |
private case class FailCont[E, O](e: E) extends Result[E, O] | |
private case class FailStop[E, O](e: E) extends Result[E, O] | |
object Result { | |
def cont[E, O](o: O): Result[E, O] = Cont(o) | |
def done[E, O](): Result[E, O] = Done() | |
def failCont[E, O](e: E): Result[E, O] = FailCont(e) | |
def failStop[E, O](e: E): Result[E, O] = FailStop(e) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment