Skip to content

Instantly share code, notes, and snippets.

@awwsmm
Last active July 23, 2021 20: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 awwsmm/40339a61f100f2ee4c0da8625f6d2bc4 to your computer and use it in GitHub Desktop.
Save awwsmm/40339a61f100f2ee4c0da8625f6d2bc4 to your computer and use it in GitHub Desktop.
Finite State Machine with state-specific commands in Scala using Akka
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors
object Test extends App {
sealed trait AnimalCommand
sealed trait DogCommand extends AnimalCommand
object Bark extends DogCommand
sealed trait HumanCommand extends AnimalCommand
object Sing extends HumanCommand
object Sit extends DogCommand with HumanCommand
def humanBehavior: Behavior[HumanCommand] =
Behaviors.receiveMessage(_ => animalBehavior.narrow[HumanCommand])
def dogBehavior: Behavior[DogCommand] =
Behaviors.receiveMessage(_ => animalBehavior.narrow[DogCommand])
def humanCommandHandler(command: HumanCommand): Unit =
command match {
case Sing => println("la la la")
case Sit => println("uh, okay")
}
def dogCommandHandler(command: DogCommand): Unit =
command match {
case Bark => println("woof")
case Sit => println("...")
}
def animalBehavior: Behavior[AnimalCommand] =
Behaviors.receiveMessage {
case command: DogCommand =>
dogCommandHandler(command)
Behaviors.same
case command: HumanCommand =>
humanCommandHandler(command)
Behaviors.same
}
}
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors
object Test extends App {
object AppleState {
sealed trait AppleStateCommand
object DoAppleThing extends AppleStateCommand
def apply(): Behavior[AppleStateCommand] =
Behaviors.receiveMessage {
case DoAppleThing => ???
case command: FruitCommand => command match {
case DoFruitThing => ???
}
}
}
object BananaState {
sealed trait BananaStateCommand
object DoBananaThing extends BananaStateCommand
def apply(): Behavior[BananaStateCommand] =
Behaviors.receiveMessage {
case DoBananaThing => ???
case command: FruitCommand => command match {
case DoFruitThing => ???
}
}
}
import AppleState._
import BananaState._
sealed trait FruitCommand extends BananaStateCommand with AppleStateCommand
object DoFruitThing extends FruitCommand
def juicer[T <: FruitCommand](fruit: Behavior[T]) = ???
juicer(AppleState())
juicer(BananaState())
def mysteryFruit: Behavior[FruitCommand] = ???
juicer(mysteryFruit)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment