Reputation: 30310
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.
Upvotes: 2
Views: 2815
Reputation: 18663
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
Upvotes: 1
Reputation: 48410
The type of ZIO.fromOption(o)
is IO[Unit, A]
which is ZIO[Any, Unit, A]
, whilst the type of ZIO.fromFuture
is Task[A]
which is ZIO[Any, Throwable, A]
, as documented by Type Aliases. Thus the types do not align
ZIO[Any, Unit, A]
ZIO[Any, Throwable, A]
Try mapError
to align the error types to Throwable
like so
for {
o <- ZIO.fromFuture { implicit ec => foo("test") }
i <- ZIO.fromOption(o).mapError(_ => new RuntimeException("boom"))
s <- ZIO.fromFuture { implicit ec => bar(i)}
} yield s
Upvotes: 3