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
package org.justinhj | |
import zio.blocking.Blocking | |
import zio.clock.Clock | |
import zio.console._ | |
import zio.random.Random | |
import zio.system.System | |
import zio.internal.PlatformLive | |
import zio.DefaultRuntime | |
import zio._ |
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
val finalState2 = finalEvents.map(eventToState).combineAll | |
println(show"Final state 2:\n$finalState2") | |
/* Output: | |
Final state 2: | |
Account holder: Ben Johnson | |
Balance: 80 | |
*/ |
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
val (finalEntity, finalEvents) = | |
commands.foldLeft((sampleAccount, List.empty[BankAccountEvent])) { | |
case ((acc, events), cmd) => | |
val newEvents = acc.processCommand(cmd) | |
val newAcc = newEvents.foldLeft(acc) { | |
case (acc, evt) => | |
acc.processEvent(evt) | |
} | |
(newAcc, events ++ newEvents) | |
} |
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
val t1 = Instant.now | |
val sampleAccount = AccountEntity(1, AccountState(0, None)) | |
val commands = List( | |
DepositCmd(t1.plusSeconds(10), 100), | |
PurchaseCmd(t1.plusSeconds(20), 120), | |
AssignAccountHolderCmd(t1.plusSeconds(40), "Bob Johnson"), | |
DepositCmd(t1.plusSeconds(40), 100), | |
AssignAccountHolderCmd(t1.plusSeconds(50), "Ben Johnson"), |
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
case class AccountEntity(id: Int, state: AccountState) | |
extends PersistentEntity[Int, AccountEntity] { | |
override type Command = BankAccountCommand | |
override type Event = BankAccountEvent | |
override type State = AccountState | |
// Applies the command to the current state, returning a list of events | |
def processCommand(command: Command) : List[Event] = { | |
command match { |
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
def eventToState(event: BankAccountEvent): AccountState = { | |
event match { | |
case DepositEvt(time, amount) => | |
AccountState(amount, None) | |
case PurchaseEvt(time, amount) => | |
AccountState(-amount, None) | |
case AssignAccountHolderEvt(time, accountHolder) => | |
AccountState(0, accountHolder.some) | |
} | |
} |
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
// When the left and right hand side are set we take the right side | |
(LastOption("Nero".some) |+| LastOption("Titus".some)).show | |
// res1: String = "Titus" | |
// When the left is None and the right hand side is set we also take the right side | |
(LastOption(None: Option[String]) |+| LastOption("Titus".some)).show | |
// res2: String = "Titus" | |
// When the left side is set and the right side is None we keep the left side | |
(LastOption("Nero".some) |+| LastOption(None: Option[String])).show |
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
AccountState(100, "Nero".some) |+| AccountState(120, "Titus".some) | |
// res1: AccountState = AccountState(220, Some("NeroTitus")) |
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
case class AccountState(balance: Int, accountHolder: LastOption[String]) | |
object AccountState { | |
implicit def accountStateShow[A] = new Show[AccountState] { | |
def show(a: AccountState): String = { | |
show"Balance: ${a.balance}\nAccount holder: ${a.accountHolder}" | |
} | |
} | |
implicit val accountMonoid = new Monoid[AccountState] { |
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
sealed trait BankAccountCommand | |
case class DepositCmd(time: Instant, amount: Int) extends BankAccountCommand | |
case class PurchaseCmd(time: Instant, amount: Int) extends BankAccountCommand | |
case class AssignAccountHolderCmd(time: Instant, accountHolder: String) extends BankAccountCommand | |
sealed trait BankAccountEvent | |
case class DepositEvt(time: Instant, amount: Int) extends BankAccountEvent | |
case class PurchaseEvt(time: Instant, amount: Int) extends BankAccountEvent | |
case class AssignAccountHolderEvt(time: Instant, accountHolder: String) extends BankAccountEvent |