Skip to content

Instantly share code, notes, and snippets.

@seigert
Last active November 20, 2023 17:08
Show Gist options
  • Select an option

  • Save seigert/cf53a0e641a38ab57dfa2aa4e4f4c02f to your computer and use it in GitHub Desktop.

Select an option

Save seigert/cf53a0e641a38ab57dfa2aa4e4f4c02f to your computer and use it in GitHub Desktop.
Memoizing example for CE3
//> using scala "3.3.1"
//> using option "-new-syntax"
//> using option "-Ykind-projector:underscores"
//> using lib "org.typelevel::cats-effect::3.5.2"
import cats._
import cats.effect._
import cats.effect.std.Random
import cats.effect.syntax.all._
import cats.syntax.all._
final case class Output(s: String)
sealed trait Res[F[_]]:
def execute: F[Output]
sealed trait MemoRes[F[_]] extends Res[F]
object MemoRes:
def apply[F[_]: Async](res: Res[F]): F[MemoRes[F]] =
res.execute.memoize.map: fa =>
new MemoRes[F]:
val execute: F[Output] = fa
final class A[F[_]: Functor](rnd: Random[F]) extends Res[F]:
val execute: F[Output] =
rnd.nextInt.map: i =>
Output(i.toString)
object A:
def apply[F[_]: Sync]: F[A[F]] =
Random.scalaUtilRandom[F].map(new A(_))
final class B[F[_]: Applicative](res: Res[F], rnd: Random[F]) extends Res[F]:
val execute: F[Output] =
(res.execute, rnd.nextInt).mapN: (out, i) =>
Output(s"${out.s} and then $i")
object B:
def apply[F[_]: Sync](res: Res[F]): F[B[F]] =
Random.scalaUtilRandom[F].map(new B(res, _))
object HelloWorld extends IOApp.Simple:
def exec(r: Res[IO], name: String) =
r.execute.flatMap(out => IO.println(s"$name: $out")).replicateA(2)
val run: IO[Unit] = for
a <- A[IO]
_ <- exec(a, "Random A")
b <- B[IO](a)
_ <- exec(b, "Random B")
mA <- MemoRes(a)
_ <- exec(mA, "Memo A")
bMA <- B[IO](mA)
_ <- exec(bMA, "Memo A, Random B")
mB <- MemoRes(bMA)
_ <- exec(mB, "Memo A, Memo B")
yield ()
/* Example output:
$> scala-cli Resource.scala
Compiling project (Scala 3.3.1, JVM)
Compiled project (Scala 3.3.1, JVM)
Random A: Output(-1900047113)
Random A: Output(-2043093384)
Random B: Output(-97920439 and then -1453735903)
Random B: Output(740318208 and then -1538324097)
Memo A: Output(-120078346)
Memo A: Output(-120078346)
Memo A, Random B: Output(-120078346 and then -652810765)
Memo A, Random B: Output(-120078346 and then -1886247155)
Memo A, Memo B: Output(-120078346 and then -1758247976)
Memo A, Memo B: Output(-120078346 and then -1758247976)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment