Vidya
Vidya

Reputation: 30310

Composing Multiple Futures and Option in Scala with ZIO

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:

I am not sure how to parse those possibilities in this scenario with ZIO. Any help is appreciated.

Upvotes: 2

Views: 2815

Answers (2)

paulpdaniels
paulpdaniels

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

Mario Galic
Mario Galic

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

Related Questions