Skip to content

Instantly share code, notes, and snippets.

@jimleroyer
Created September 26, 2017 22:13
Show Gist options
  • Save jimleroyer/943efd00c764880b8119786d9dd6c3a2 to your computer and use it in GitHub Desktop.
Save jimleroyer/943efd00c764880b8119786d9dd6c3a2 to your computer and use it in GitHub Desktop.
Scala Workflow using Any and Nothing types
import scala.language.existentials
// Simple laboratory exercise that uses incompatible parameter types, as the
// [[State]] type parameter is bound to [[Nothing]], and nothing above. That
// does not make sense at all.
object Lab {
/** ************** Types */
trait StateDef {
def id: String
}
case class State[+CV](override val id: String, context: CV) extends StateDef
trait Action[-P, +R]
abstract class Condition[-T] extends Function1[T, Boolean] {
override def apply(contextState: T): Boolean
}
case class Transition[-P, +R](tailState: StateDef, headState: StateDef, action: Action[P, R], condition: Option[Condition[P]] = None)
case class Workflow private(transitions: List[Transition[Nothing, Any]]) {
def getTransitions(tail: StateDef, head: StateDef): List[Transition[Nothing, Any]] = {
transitions.filter(t => true)
}
def matchTransition[P <: Nothing](tail: State[P], head: StateDef): Option[Transition[Nothing, Any]] = {
val value = tail.context
val transitions: List[Transition[Nothing, Any]] = getTransitions(tail, head)
transitions.find(t => t.condition.forall(cond => cond(value)))
}
}
/** ************** Fixtures */
// Model
case class CreateImage()
case class Image()
// States
class Init extends State[CreateImage]("INIT", CreateImage())
val init = new Init()
case object Published extends StateDef {
override def id: String = "PUBLISHED"
}
// Action
class CreateTipAction extends Action[CreateImage, Image]
/** ************** Demo */
val transitions = List(
Transition(init, Published, new CreateTipAction())
)
val w = Workflow(transitions)
val t = w.matchTransition(init, Published)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment