Skip to content

Instantly share code, notes, and snippets.

@filosganga
Last active Mar 5, 2020
Embed
What would you like to do?
Computational memoization
import cats._
import cats.implicits._
import cats.effect._
import cats.effect.concurrent._
import cats.effect.implicits._
trait Memoize[F[_], Key, A] {
def get(id: Key): F[A]
}
object Memoize {
def apply[F[_]: Concurrent, Key, A](f: Key => F[A]): F[Memoize[F, Key, A]] =
Ref[F].of(Map.empty[Key, Deferred[F, Either[Throwable, A]]]).map { state =>
new Memoize[F, Key, A] {
def get(id: Key): F[A] =
Deferred[F, Either[Throwable, A]].flatMap { deferred =>
state
.modify { hashMap =>
val completeDeferred = f(id).attempt
.flatTap(deferred.complete)
.uncancelable
hashMap.get(id) match {
case None => (hashMap + (id -> deferred), completeDeferred)
case Some(d) => (hashMap, d.get)
}
}
.flatten
.rethrow
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment