Skip to content

Instantly share code, notes, and snippets.

@jimleroyer
Created September 27, 2017 04:45
Show Gist options
  • Save jimleroyer/2cb4ccbec13620585d21d53b4431ce22 to your computer and use it in GitHub Desktop.
Save jimleroyer/2cb4ccbec13620585d21d53b4431ce22 to your computer and use it in GitHub Desktop.
Scala Workflow using forSome existentials Raw (with proper scope this time)
import scala.language.existentials
// Simple laboratory exercise that uses existentials everywhere for the Transition.
// But these existentials are not bound to much restriction and are not recognized
// to be compatible with the built list of transitions.
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[P, R] forSome {type P; type R}]) {
def getTransitions[V](tail: StateDef, head: StateDef): List[Transition[P, R] forSome {type P >: V; type R}] = {
transitions.filter(t => true).map(t => t.asInstanceOf[Transition[V, _]])
}
def matchTransition[V](tail: State[V], head: StateDef): Option[Transition[P, R] forSome {type P >: V; type R}] = {
val value = tail.context
val transitions = getTransitions[V](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