Skip to content
No description, website, or topics provided.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci Fix tag to reflect new versioning scheme (#4) Jun 24, 2019
project Update sbt to 1.3.0 (#19) Sep 6, 2019
src/main/scala/zio/interop Replace succeedLazy with succeed (#20) Sep 6, 2019
.gitattributes Add license & readme Jun 10, 2019
.scalafmt.conf Update scalafmt-core to 2.0.1 (#15) Aug 19, 2019
LICENSE Add license & readme Jun 10, 2019 Set CI badge (#3) Jun 24, 2019
build.sbt Update zio to 1.0.0-RC12-1 (#18) Sep 6, 2019
sbt Setup SBT project Jun 10, 2019

Interop Future


This library provides an interoperability layer with Scala's Future.

From 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 the Future value, is a thunk (or Function0). The reason for that is, Future is eager, it means as soon as you call Future.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 creating Futures using def instead of val.
  • 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 to Throwable since that's the only possible cause for a failed Future.


// 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)

To Future

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)
You can’t perform that action at this time.