Skip to content

Instantly share code, notes, and snippets.

@ChristopherDavenport
Last active October 12, 2018 17:14
Show Gist options
  • Save ChristopherDavenport/0edee8368031c826f5b0aa0eeb30e590 to your computer and use it in GitHub Desktop.
Save ChristopherDavenport/0edee8368031c826f5b0aa0eeb30e590 to your computer and use it in GitHub Desktop.
Currency Quick Evaluation
import cats.effect._
import cats.effect.implicits._
import cats.effect.concurrent._
import cats.implicits._
import cats._
import cats.temp.par._
object ConcurrentSuccess{
def parAttempt[G[_]: Traverse, F[_]: Par: MonadError[?[_], Throwable], A](xs: G[F[A]]): F[G[Either[Throwable, A]]] =
xs.parTraverse(_.attempt)
def parAttempt2[G[_]: Traverse, F[_]: Concurrent, A](l: G[F[A]]): F[G[Either[Throwable, A]]] = {
val intermediate: F[G[Fiber[F, Either[Throwable, A]]]] = l.traverse(_.attempt.start)
intermediate.flatMap(_.traverse(_.join))
}
def firstComplete[G[_]: Traverse, F[_]: Concurrent, A](l: G[F[A]]): F[Option[A]] = for {
deferred <- Deferred[F, Option[A]]
gFibers <- l.traverse(_.flatMap(a => deferred.complete(a.some).attempt).start)
completeEmpty <- (gFibers.traverse_(_.join) *> deferred.complete(None).attempt).start
value <- deferred.get
.guarantee(
gFibers.traverse(_.cancel.attempt.start).start.void *>
completeEmpty.cancel.start.void
)
} yield value
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment