Convert scala 2.10 future to scalaz.concurrent.Future // Task
Asked Answered
D

2

12

did anybody come to piece of code how to properly convert scala's Future (2.10) to new scalaz7 future ? I know hot to convert scalaz future via scala Promise to scala Future, but not sure how to do it properly around

For example

import scalaz.concurrent.{Future => Zuture}
import scala.concurrent.Future

I want to have implementation of

implicit def scalaF2scalazF[A](in:Future[A]):Zuture[A]=???

Then obviously would be piece of cake to write

implicit def scalaF2scalazTask[A](in:Future[A]):Task[A]=???

because thats is what I really want :-)

Dardar answered 3/6, 2013 at 11:25 Comment(2)
Did you see the scalaz-contrib library? There are some instances for scala.concurrent.Future there.Blockhouse
Thanks for pointing out. However I understood these are to convert scala futures to scalaz Monad/monoids/semigroups. Not sure how this can be used in piece of code that uses Tasks/scalaz.Future. Can you please suggest small example of code how you would link the code where you have hardcoded Task (i.e. scalaz-stream) with one's that use scala's future (i.e. play iteratees)?Dardar
D
21

After evaluating couple of alternatives I have come to following solution. Obviously if someone wantsscalaz.Monad[scala.concurrent.Future], scalaz.std.scalaFuture https://github.com/scalaz/scalaz/blob/series/7.2.x/core/src/main/scala/scalaz/std/Future.scala#L85 is the way to go.

object ScalaFutureConverters {


  implicit def scalaFuture2scalazTask[T](fut: Future[T])(implicit ec: ExecutionContext): Task[T] = {
    Task.async {
      register =>
        fut.onComplete {
          case Success(v) => register(v.right)
          case Failure(ex) => register(ex.left)
        }
    }
  }


  implicit def scalazTask2scalaFuture[T](task: Task[T]): Future[T] = {
    val p: Promise[T] = Promise()

    task.runAsync {
      case -\/(ex) => p.failure(ex)
      case \/-(r) => p.success(r)
    }

    p.future
  }


  implicit class ScalazFutureEnhancer[T](task: Task[T]) {
    def asScala: Future[T] = scalazTask2scalaFuture(task)
  }


  implicit def scalaF2EnhancedScalaF[T](fut: Future[T])(implicit ec: ExecutionContext): ScalaFEnhancer[T] =
    ScalaFEnhancer(fut)(ec)

  case class ScalaFEnhancer[T](fut: Future[T])(implicit ec: ExecutionContext) {
    def asTask: Task[T] = scalaFuture2scalazTask(fut)(ec)
  }

}

This solution however also runs the task once the conversion to scala future is made which may/may not be desired, depending on situation.

Dardar answered 29/6, 2013 at 7:18 Comment(2)
The link in the beginning of the answer is now broken.Demoiselle
fixed link in the beginning of the answerLoosejointed
D
1

You can also use https://github.com/Verizon/delorean which adds convenient toTask and toFuture methods

Divalent answered 10/7, 2017 at 18:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.