Skip to content

Instantly share code, notes, and snippets.

@marko-asplund
Created November 3, 2018 21:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marko-asplund/a6449e6bb6f4dae2dac50dff78e81e70 to your computer and use it in GitHub Desktop.
Save marko-asplund/a6449e6bb6f4dae2dac50dff78e81e70 to your computer and use it in GitHub Desktop.
Lift Future[A] to F[A]
/*
adapted from:
https://github.com/monix/monix/blob/4f1862c4bcad7d111aa8cf64510c2fc5dcee6b77/monix-catnap/shared/src/main/scala/monix/catnap/FutureLift.scala
Monix dependency removed.
*/
package async {
import cats.effect.Async
import scala.concurrent.Future
import scala.language.higherKinds
trait FutureLift[F[_]] {
def futureLift[MF[T] <: Future[T], A](fa: F[MF[A]]): F[A]
}
object FutureLift {
def apply[F[_]](implicit F: FutureLift[F]): FutureLift[F] = F
def toAsync[F[_], MF[T] <: Future[T], A](fa: F[MF[A]])
(implicit F: Async[F]): F[A] = {
F.flatMap(fa) { future =>
future.value match {
case Some(value) => F.fromTry(value)
case _ => startAsync(future)
}
}
}
private def start[A](fa: Future[A], cb: Either[Throwable, A] => Unit): Unit = {
import concurrent.ExecutionContext.Implicits.global // TODO
fa.onComplete { r =>
cb(r match {
case scala.util.Success(a) => Right(a)
case scala.util.Failure(t) => Left(t)
})
}
}
private def startAsync[F[_], A](fa: Future[A])(implicit F: Async[F]): F[A] =
F.async { cb => start(fa, cb) }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment