Last active
June 16, 2018 01:14
-
-
Save smarter/9a28e39dfaf0235e9d0a16b09ff8a9a4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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