Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Created December 19, 2017 06:23
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/24826581af9a804334139a9f0488e9c8 to your computer and use it in GitHub Desktop.
Save yasuabe/24826581af9a804334139a9f0488e9c8 to your computer and use it in GitHub Desktop.
by eff monad
import cats.data.{State, Writer}
import org.atnos.eff._
import org.atnos.eff.state._
import org.atnos.eff.writer._
import org.atnos.eff.syntax.all._
case class CashRegister(total: Int) {
def addCash(toAdd: Int) = CashRegister(total + toAdd)
}
type Purchase = CashRegister => CashRegister
def makePurchase(amount: Int): Purchase = (r: CashRegister) => {
println("Purchase in amount: " + amount)
r addCash amount
}
type Stack = Fx.fx2[State[CashRegister, ?], Writer[Purchase, ?]]
type _writerVector[R] = Writer[Purchase, ?] |= R
type _stateRegister[R] = State[CashRegister, ?] |= R
def execute[R :_stateRegister :_writerVector](p: Purchase): Eff[R, Unit] = for {
_ <- tell(p)
_ <- modify(p(_))
} yield ()
// test -------------------------------------------------------------------
val p1 = makePurchase(100)
val p2 = makePurchase(50)
def program = for {
_ <- execute[Stack](p1)
_ <- execute[Stack](p2)
} yield ()
val ((_, last), history) = program.runState(CashRegister(0)).runWriter.run
// 再実行
val total2 = history.foldLeft(CashRegister(10))((acc, p) => p(acc))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment