If i just use Option in for-comprehension everything goes as expected:
val a = Some(1)
val b = None
val c = Some(3)
val r = for {
aa <- a
bb <- b
cc <- c
} yield aa + bb + cc
println(r) // None, because b is None
but how to achieve the same behaviour using cats IO?
import cats.effect.IO
// in reality this will be a methods with side effect
val a = Some(1)
val b = None
val c = Some(3)
val r = for {
_ <- IO{println("a"); a}
_ <- IO{println("b"); b} // want to stop execution here
_ <- IO{println("c"); c}
} yield ()
r.unsafeRunSync()
In result i get a b c
, but i expect only a b
.
Is it possible to achieve? Is it a right way to do it?
You can do this with monad transformers; specifically, you'll want to use OptionT[IO, T]
here:
import cats.effect._
import cats.data.OptionT
import cats.implicits._
import cats.effect.IO
val a = Some(1)
val b = None
val c = Some(3)
val r = for {
_ <- OptionT[IO, Int](IO {println("a"); a})
_ <- OptionT[IO, Int](IO {println("b"); b})
_ <- OptionT[IO, Int](IO {println("c"); c})
} yield ()
r.value.unsafeRunSync()
See it in action here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With