Skip to content

Instantly share code, notes, and snippets.

@chuwy
Created March 1, 2018 11:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chuwy/d9c9f2442d198350edf88e9f003959a4 to your computer and use it in GitHub Desktop.
Save chuwy/d9c9f2442d198350edf88e9f003959a4 to your computer and use it in GitHub Desktop.
Interleaving lazy and eager evaluation to break referential transparency
import cats._
import cats.implicits._
import cats.effect._
import cats.effect.implicits._
object Db {
private val cache = collection.mutable.Map.empty[String, String]
def expensiveIO(input: String): IO[String] =
IO { Thread.sleep(1000); println("Executed expensive action"); input ++ input }
def get(input: String): IO[String] = {
cache.get(input) match {
case Some(output) =>
IO(output)
case None =>
for {
res <- expensiveIO(input)
_ = cache.put(input, res)
} yield res
}
}
}
object Time {
def process(input: String): IO[Unit] = {
val time = System.currentTimeMillis()
for {
_ <- IO { println(s"Processing ${input} at ${time}") }
_ <- IO { println(s"Real time is ${System.currentTimeMillis()}") }
} yield ()
}
/** Imitate a blocking action */
val dbQuery: IO[List[String]] = IO {
Thread.sleep(2000)
List("one", "two", "three")
}
def run(): IO[Unit] =
for {
inputs <- dbQuery
_ <- inputs.traverse(process)
_ <- dbQuery // another blocking call to illustrate a problem
_ <- IO { println(s"Done processing at ${System.currentTimeMillis()}") }
} yield ()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment