Last active
November 20, 2023 17:08
-
-
Save seigert/cf53a0e641a38ab57dfa2aa4e4f4c02f to your computer and use it in GitHub Desktop.
Memoizing example for CE3
This file contains hidden or 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
| //> 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