Skip to content

Instantly share code, notes, and snippets.

View justinhj's full-sized avatar

Justin Heyes-Jones justinhj

View GitHub Profile
@justinhj
justinhj / PE5.scala
Last active December 18, 2019 05:05
.onEvent {
case (WithdrawEvt(time, description, amount), state) =>
AccountState(state.balance - amount)
case (DepositEvt(time, description, amount), state) =>
AccountState(state.balance + amount)
case (AssignAccountHolderEvt(time, accountHolder), state) =>
Account(state.balance, Some(accountHolder))
}
.onCommand[WithdrawCmd, WithdrawalResponse]{
case (WithdrawCmd(time, description, amount), ctx, state) =>
if(state.balance - amount >= 0)
ctx.thenPersist(WithdrawEvt(time, description, amount)){ _ =>
ctx.reply(SuccessfulWithdrawalResponse(state.balance - amount))
}
else {
ctx.reply(FailedWithdrawalResponse(s"Insufficient funds (current balance ${state.balance})"))
ctx.done
}
override def behavior = {
Actions().onCommand[DepositCmd, Int]{
case (DepositCmd(time, description, amount), ctx, state) =>
ctx.thenPersist(DepositEvt(time, description, amount)){ _ =>
ctx.reply(state.balance + amount)
}
// ...
@justinhj
justinhj / PE2.scala
Last active December 17, 2019 06:47
sealed trait BankAccountCommand[R] extends ReplyType[R]
case class DepositCmd(time: Instant, description: String, amount: Int)
extends BankAccountCommand[Int]
case class WithdrawCmd(time: Instant, description: String, amount: Int)
extends BankAccountCommand[WithdrawalResponse]
case class AssignAccountHolderEvt(time: Instant, accountHolder: String)
extends BankAccountEvent
@justinhj
justinhj / pe1.scala
Last active December 18, 2019 05:04
PE1
case class Account(balance: Int, accountHolder: Option[String])
class BankAccountEntity extends PersistentEntity {
override type Command = BankAccountCommand[_]
override type Event = BankAccountEvent
override type State = AccountState
override def initialState : State = Account(0, None)
def behavior = ??? // To come later
@justinhj
justinhj / CustomEC.scala
Created November 12, 2019 00:55
Custom Scala execution context
// Create a custom threadpool and execution context for Akka to use
val executor: ExecutorService = Executors.newFixedThreadPool(4, new ThreadFactory() {
override def newThread(r: Runnable): Thread = {
val t = Executors.defaultThreadFactory.newThread(r)
t.setDaemon(true)
t
}
})
@justinhj
justinhj / listoptionfor.scala
Created September 11, 2019 04:58
List and Option in for
// Ammonite repl output
@ desugar {
for (
s <- List(1,2,3);
o <- if(s % 2 == 1) Some(s) else None
) yield (s + o)
}
res12: Desugared = scala.collection.immutable.List.apply[Int](1, 2, 3).flatMap[Int, Any](((s: Int) => scala.Option.option2Iterable[Int]((if (s.%(2).==(1))
scala.Some.apply[Int](s)
@justinhj
justinhj / EitherTLogging.scala
Created July 28, 2019 05:39
Error handling and logging
import cats._
import cats.data._
import cats.implicits._
object EitherTLogging {
def divide[F[_]](dividend: Int, divisor: Int)(implicit F: ApplicativeError[F, String]): F[Int] = {
if (divisor === 0) F.raiseError("division by zero")
else F.pure(dividend / divisor)
}
@justinhj
justinhj / WriterTFailure.scala
Created July 27, 2019 07:02
WriterT failing
import cats._
import cats.instances._
import cats.syntax._
import cats.data.Validated._
type ErrorOr[A] = Validated[String, A]
def logDivide(a: Int, b: Int) = WriterT[ErrorOr, String, Int](
divide[ErrorOr](a,b) match {
case Invalid(e) => Invalid("Division by zero\n")
@justinhj
justinhj / typeclasspatternexample.scala
Created July 16, 2019 15:49
From @Kaishh on functional programming Slack
// kaishh [4:20 AM]
// Found a neat way to always have typeclass syntax available without any wildcards imports:
package mypkg {
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
final class FunctorOps[F[_], A](private val fa: F[A]) extends AnyVal {
def map[B](f: A => B)(implicit F: Functor[F]): F[B] = F.map(fa)(f)
}