Skip to content

Instantly share code, notes, and snippets.

View justinhj's full-sized avatar

Justin Heyes-Jones justinhj

View GitHub Profile
@justinhj
justinhj / traverseFilter.scala
Last active April 6, 2020 18:15
It's always Traverse!
import cats._
import cats.implicits._
import cats.data.Const
// List version
Traverse[List].traverse(List(1,2,3,4,5,6))(a => if(a%2==0) Const.of[Any](List(a)) else Const.of[Any](List.empty[Int])
).getConst
res7: List[Int] = List(2, 4, 6)
@justinhj
justinhj / StateTEither.scala
Created June 23, 2019 21:48
StateT with Either for error handling
import cats._
import cats.implicits._
import cats.data.StateT
object Radio {
case class Radio(volume: Int)
type RadioError = String
type RadioEither[A] = Either[RadioError, A]
type RadioStateEitherT[A] = StateT[RadioEither, Radio, A]
@justinhj
justinhj / purefp1.scala
Created March 12, 2020 18:29
A pure function
def functionExample(a: A): B = {
// ... do something with A
// .. return a value of type B
}
@justinhj
justinhj / MyThrowable.scala
Last active February 25, 2020 02:36
I called this Throwable but it's actually just an implementation of Try (and Functor/Monad instance of it)
object MyThrowable {
// This is just here to keep Wartremover happy
@SuppressWarnings(Array("org.wartremover.warts.Equals"))
implicit final class AnyOps[A](self: A) {
def ===(other: A): Boolean = self == other
}
// Define Try and make it a monad/functor
sealed trait Try[+T]
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._
val finalState2 = finalEvents.map(eventToState).combineAll
println(show"Final state 2:\n$finalState2")
/* Output:
Final state 2:
Account holder: Ben Johnson
Balance: 80
*/
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)
}
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"),
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 {
trait PersistentEntity[IDType, T <: PersistentEntity[IDType, T]] {
type Command
type Event
type State
def id: IDType
def state : State
def processCommand(command: Command) : List[Event]
def processEvent(event: Event) : T