scala - For-Comprehension Example with \/ and IO -
given following foo
case class:
scala> case class foo(x: int) defined class foo
i check if it's valid foo
before constructing inside of validatefoo
:
scala> def validatefoo(foo: foo): \/[string, foo] = (if(foo.x > 0) foo.success[string] else ("invalid foo").failure[foo]).disjunction validatefoo: (foo: foo)scalaz.\/[string,foo]
lastly, f
creates foo
, , tries perform io
action (example: save foo
database).
scala> def f(x: foo): io[\/[string,int]] = { | foo <- validatefoo(x) | iofoo <- io { foo } | } yield iofoo <console>:19: error: type mismatch; found : scalaz.effect.io[foo] required: scalaz.\/[?,?] iofoo <- io { foo } ^ <console>:18: error: type mismatch; found : scalaz.\/[string,nothing] required: scalaz.effect.io[scalaz.\/[string,int]] foo <- validatefoo(x) ^
however, ran above issue when trying chain bind
's in for-comprehension.
the problem, see it, proper return type io[\/[string, int]]
. however, don't know how validate foo
and handle in io
monad for-comprehension.
you can't combine string \/ a
, io[a]
computations this—if desugared for
-comprehension you'd see types don't work out.
if wanted to, use monad transformer compose 2 monads. suppose have following setup, example (which code, cleaned bit, , new method representing database operation):
import scalaz._, scalaz._, effect._ case class foo(x: int) def validatefoo(foo: foo): string \/ foo = (foo.x > 0) either foo or "invalid foo" def processfoo(foo: foo): io[foo] = io { println(foo) foo }
now can write following:
type iostringor[a] = eithert[io, string, a] def f(x: foo): iostringor[foo] = { foo <- eithert(validatefoo(x).point[io]) iofoo <- processfoo(foo).liftio[iostringor] } yield iofoo
now can run eithert
io
action:
val ioaction: io[string \/ foo] = f(foo(10)).run
that's how could use \/
, io
in for
-comprehension. it's pretty overkill in case, though. i'd write this:
def f(x: foo): io[string \/ foo] = validatefoo(x).bitraverse(_.point[io], processfoo)
this uses bitraverse
instance \/
map function io
on both sides of disjunction , turn whole thing inside out.
Comments
Post a Comment