I just started evaluating ZIO to improve the programming model and the performance of my asynchronous Scala code. In my code base I deal with Future[Option[T]]
often, and to this point I have dealt with that using Scalaz's OptionT
monad transformer. Now I want to try this with ZIO.
Consider two functions:
def foo: String => Future[Option[T]]
and
def bar: T => Future[U]
I tried something like this:
val t = for {
o: Option[Int] <- ZIO.fromFuture { implicit ec =>
foo("test")
}
i: Int <- ZIO.fromOption(o)
s: String <- ZIO.fromFuture { implicit ec =>
bar(i)
}
} yield s
According to my IDE, t
is of type ZIO[Any, Any, String]
in this scenario. I don't know what to do with that.
I want to consider three possibilities:
foo
produces a Some
that can be composed with other functions on the valuefoo
produces a None
I am not sure how to parse those possibilities in this scenario with ZIO. Any help is appreciated.
There are couple operators that can help you out in this case, basically instead of explicitly unwrapping the Option
with fromOption
, I would recommend using a combination of some
and asSomeError
val t: Task[Option[String]] = (for {
// This moves the `None` into the error channel
i: Int <- ZIO.fromFuture(implicit ec => foo("test")).some
// This wraps the error in a Some() so that the signature matches
s: String <- ZIO.fromFuture(implicit ec => bar(i)).asSomeError
} yield s).optional // Unwraps the None back into the value channel