Delimited continuations allow functional effects to be expressed in a
direct style, eliminating the need for nested flatMap
callbacks and for
comprehensions.
Jellyfish is a Scala library for direct-style functional dependency injection via delimited continuations.
import scala.language.higherKinds
import scala.util.continuations.shift
import scala.util.continuations.reset
import scala.util.continuations.cpsParam
import cats.Monad
import cats.effect.IO
import cats.effect.IOApp
import cats.effect.std.Console
object Main extends IOApp.Simple {
def extract[F[_]: Monad, A](x: F[A]): A @cpsParam[F[Unit], F[Unit]] =
{ k: (A => F[Unit]) =>
shift [Monad[F]].flatMap(x)(k)
implicitly}
override val run: IO[Unit] =
{
reset val x: Int = extract(IO.pure(6))
val y: Int = extract(IO.pure(7))
val z: Int = x * y
Console[IO].println(z)
}
}
This file is literate Scala, and can be run using Codedown:
$ curl https://earldouglas.com/jellyfish.md |
codedown scala |
scala-cli \
--scala 2.12.2 \
--jvm 17 \
--compiler-plugin org.scala-lang.plugins:::scala-continuations-plugin:1.0.3 \
--dependency org.scala-lang.plugins::scala-continuations-library:1.0.3 \
--dependency org.typelevel::cats-effect:3.5.4 \
-P:continuations:enable \
_.scala
42