Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Created December 19, 2017 06:25
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 yasuabe/c9e6368d1103ac79c8aabcc0219caab5 to your computer and use it in GitHub Desktop.
Save yasuabe/c9e6368d1103ac79c8aabcc0219caab5 to your computer and use it in GitHub Desktop.
by io monad
// program 中のregisterの持ち回りを避ける
import cats.data.StateT
import cats.effect.IO
case class CashRegister(total: Int) {
def addCash(toAdd: Int) = CashRegister(total + toAdd)
}
type Purchase = CashRegister => IO[CashRegister]
def makePurchase(amount: Int): Purchase = (r: CashRegister) => for {
_ <- IO { println ("Purchase in amount: " + amount) }
} yield r addCash amount
type PurchaseHistory = Vector[Purchase]
def execute(p: Purchase): StateT[IO, (PurchaseHistory, CashRegister), Unit] =
StateT { case (h, r) => p(r) map { r2 => ((h :+ p, r2), ()) }}
// test -------------------------------------------------------------------
val p1 = makePurchase(100)
val p2 = makePurchase(50)
def program = for {
_ <- execute(p1)
_ <- execute(p2)
} yield ()
val io1 = program.runS((Vector.empty, CashRegister(0)))
val (history, last) = io1.unsafeRunSync()
val io2 = history.foldLeft(IO.pure(CashRegister(10)))(_ flatMap _)
io2.unsafeRunSync()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment