Scalaz Task ↔ Scala Future
Since many asynchronous APIs in Scala use Future
s, 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
.