scala - Sequencing both Scalaz WriterT and Either with for-yield -
if have:
import scala.concurrent._ import scalaz._, scalaz._ type z = list[string] type f[α] = future[α] type wt[α] = writert[f, z, α] implicit val z: monoid[z] = new monoid[z] { def 0 = nil def append (f1: z, f2: => z) = f1 ::: f2 } implicit val f: monad[f] = scalaz.std.scalafuture.futureinstance
i can write code this:
def fooa (): wt[int] = writert.put[f, z, int] (f.point (18))(z.zero) def foob (): wt[int] = writert.put[f, z, int] (f.point (42))(z.zero) def foolog (msg: string): wt[unit] = writert.put[f, z, unit] (f.point (()))(msg :: nil)) def foo (): wt[int] = { _: unit <- foolog ("log #1") a: int <- fooa _: unit <- foolog ("log #2") b: int <- foob _: unit <- foolog ("log #3") } yield + b
suppose define:
type wtt[α] = writert[future, z, throwable \/ α] def flakeyint (i: int): throwable \/ int = new java.util.random().nextboolean match { case false => i.right case true => new exception (":-(").left }
i can write this:
def bara (): wtt[int] = writert.put[f, z, throwable \/ int] (f.point (flakeyint (18)))(z.zero) def barb (): wtt[int] = writert.put[f, z, throwable \/ int] (f.point (flakeyint (42)))(z.zero) def barlog (msg: string): wtt[unit] = writert.put[f, z, throwable \/ unit] (f.point (().right))(msg :: nil)) def bar (): wtt[int] = { _: throwable \/ unit <- barlog ("log #1") x: throwable \/ int <- bara _: throwable \/ unit <- barlog ("log #2") y: throwable \/ int <- barb _: throwable \/ unit <- barlog ("log #3") } yield { { <- x b <- y } yield + b }
is there way make <-
in for-yield return type α
, not \/[throwable, α]
don't have manually flatten throwables @ end? ideally make bar
function foo
function can hide flattening errors logic.
follow question:
customising composition of future, either , writer in scalaz
you should wrap future monad in eithert, sightly modifying code. that:
type eft[α] = eithert[f, throwable, α] type weft[α] = writert[eft, z, α] def baza(): weft[int] = writert.put[eft, z, int](eithert.right[f, throwable, int](f.point(18)))(z.zero) def bar(): weft[int] = { <- baza b <- baza } yield + b
you can define lift functions (which lifts value 1 monad transformer) avoid boilerplate.
def liftw[a](fa: future[a]): wlet[a] = { writert.put[mlt, z, a](eithert.right[future, throwable, a](fa))(z.zero) } def bbar(): wlet[int] = { ← liftw(6.point[f]) b ← liftw(6.point[f]) } yield + b
i sure lift functions present in scalaz, struggling find them, , appears these easier write yourself.
Comments
Post a Comment