This library provides an interoperability layer with Scala's Future.
This is the extension method added to IO
companion object:
def fromFuture[A](ftr: () => Future[A])(ec: ExecutionContext): Task[A] =
There are a few things to clarify here:
ftr
, the expression producing theFuture
value, is a thunk (orFunction0
). The reason for that is,Future
is eager, it means as soon as you callFuture.apply
the effect has started performing, that's not a desired behavior in Pure FP (which ZIO encourages). So it's recommended to declare expressions creatingFuture
s usingdef
instead ofval
.- Also you have to be explicit on which EC you want to use, having it implicit, as in the standard library, is a bad practice.
- Finally, as you can see, the
IO
returned fixes the error type toThrowable
since that's the only possible cause for a failedFuture
.
// EC is not implicit
val myEC: ExecutionContext = ...
// future defined in thunk using def
def myFuture: Future[ALotOfData] = myLegacyHeavyJobReturningFuture(...)
val myIO: Task[ALotOfData] = IO.fromFuture(myFuture _)(myEC)
This extension method is added to values of type Task[A]
:
def toFuture: UIO[Future[A]]
Notice that we don't actually return a Future
but an infallible IO
producing the Future
when it's performed, that's again because as soon as we have a Future
in our hands, whatever it does is already happening.
As an alternative, a more flexible extension method is added to any IO[E, A]
to convert to Future
as long as you can provide a function to convert from E
to Throwable
.
def toFutureE(f: E => Throwable): UIO[Future[A]]
val safeFuture: UIO[Future[MoarData]] = myShinyNewApiBasedOnZio(...).toFuture(MyError.toThrowable)
val itsHappening: Future[MoarData] = unsafeRun(safeFuture)