Skip to content

Instantly share code, notes, and snippets.

@smarter
Last active June 16, 2018 01:14
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 smarter/9a28e39dfaf0235e9d0a16b09ff8a9a4 to your computer and use it in GitHub Desktop.
Save smarter/9a28e39dfaf0235e9d0a16b09ff8a9a4 to your computer and use it in GitHub Desktop.
// Compiles with https://github.com/lampepfl/dotty/pull/4672
// ./bin/dotc -classpath "$(coursier fetch -p org.typelevel:cats-effect_2.12:1.0.0-RC2)" out/blocking.scala
import scala.language.implicitConversions
import cats.implicits._
import cats.effect._
import scala.concurrent.ExecutionContext
object Blocking {
// If we allow context bounds in polymorphic function types we could shorten the type of p to [G[_]: Sync] -> G[A]
def blocking[F[_]: Async, A](p: [G[_]] -> implicit Sync[G] => G[A], blockingEc: ExecutionContext)(implicit ec: ExecutionContext): F[A] =
for {
_ <- Async.shift[F](blockingEc)
res <- p[F]
_ <- Async.shift(ec)
} yield res
}
object Y {
type MyType
type HttpResponse
implicit def global: ExecutionContext = ???
def blockingEC: ExecutionContext = ???
def dbCall[F[_]: Sync]: F[MyType] = ???
def asyncDbCall[F[_]: Async]: F[MyType] = ???
def post[F[_]: Async](a: MyType): F[HttpResponse] = ???
// Implementation without `blocking`
def prog1[F[_]: Async]: F[HttpResponse] =
for {
_ <- Async.shift[F](blockingEC)
myType <- dbCall[F]
_ <- Async.shift[F](global)
res <- post[F](myType)
} yield res
// Implementation with `blocking`, equivalent to prog1
def prog2[F[_]: Async]: F[HttpResponse] = {
val dbCallValue = [G[_]] -> implicit (ev: Sync[G]) => dbCall[G] // needed until we get polymorphic eta-expansion
// Bot of these things fail compilation, which is exactly what we want
// val dbCallValue = [G[_]] -> implicit (ev: Sync[G]) => asyncDbCall[G]
// val dbCallValue = [G[_]] -> implicit (ev: Sync[G]) => asyncDbCall[IO]
for {
myType <- Blocking.blocking(dbCallValue, blockingEC)
res <- post[F](myType)
} yield res
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment