Scalaz Task ↔ Scala Future

Since many asynchronous APIs in Scala use Futures, if you prefer using Task, you'll need to convert between the two. Here are two simple classes that enhance scalaz.concurrent.Task and scala.concurrent.Future:

import scalaz.concurrent.Task
import scala.concurrent.{ Promise, Future }

final class FutureExtensionOps[A](x: => Future[A]) {
  import scalaz.Scalaz._

  def asTask: Task[A] = {
    Task.async {
      register =>
        x.onComplete {
          case Success(v) => register(v.right)
          case Failure(ex) => register(ex.left)
        }(Implicits.trampoline)
    }
  }
}

final class TaskExtensionOps[A](x: => Task[A]) {
  import scalaz.{ \/-, -\/ }
  val p: Promise[A] = Promise()
  def runFuture(): Future[A] = {
    x.unsafePerformAsync {
      case -\/(ex) =>
        p.failure(ex); ()
      case \/-(r) => p.success(r); ()
    }
    p.future
  }
}

Provide an implicit conversion to augment Task/Future, or make these Ops implicit. There is a dependency on the trampoline ExecutionContext from Play's iteratees library, but you can quite easily duplicate it for yourself.

Note (2016-02-01): Updated to scalaz-7.2. If using an earlier version, use runAsync instead of unsafePerformAsync.

Stay connected

I send out occasional updates on posts, interesting finds, and projects I'm working on. I'd love to include you. No tracking, one-click unsubscribe.