> State machines are super commonly used in languages where you can (easily) construct ADTs and pattern match on them.
I had the opportunity to use F# for the first time last month, and I experienced this first hand -- it was far easier to write a procedure as a sum type with transition functions than it would have been to write it procedurally. And with all the advantages of having the states of the system and their transitions laid out explicitly, why fight it?
Unfortunately no -- NDA / work-for-hire. Customer requested .NET but didn't care which language. We usually write Python, F# felt friendlier than C#. State classes looked like:
type InitialState = {a : int; b : string}
type IntermediateState = {a : int; b: string; c: string list}
type FinishedState = {a: int; b: string}
type ErrorState = {a: int; b: string; message: string}
type State =
| UninitializedState
| InitialState of InitialState
| IntermediateState of IntermediateState
| FinishedState of FinishedState
| ErrorState of ErrorState
| FinalState
And transition functions:
let initialize (args : string list) (s:UninitializedState) : State =
// create an initial state from args, not actually like this
InitialState {a= 5; b="hello"}
I probably put too many types into my function signatures, but I'm new to this style.
I had the opportunity to use F# for the first time last month, and I experienced this first hand -- it was far easier to write a procedure as a sum type with transition functions than it would have been to write it procedurally. And with all the advantages of having the states of the system and their transitions laid out explicitly, why fight it?