Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I encode and enforce legal FSM state transitions with a type system?

Suppose I have a type Thing with a state property A | B | C,
and legal state transitions are A->B, A->C, C->A.

I could write:

transitionToA :: Thing -> Maybe Thing

which would return Nothing if Thing was in a state which cannot transition to A.

But I'd like to define my type, and the transition functions in such a way that transitions can only be called on appropriate types.

An option is to create separate types AThing BThing CThing but that doesn't seem maintainable in complex cases.

Another approach is to encode each state as it's own type:

data A = A Thing
data B = B Thing
data C = C Thing

and

transitionCToA :: C Thing -> A Thing

This seems cleaner to me. But it occurred to me that A,B,C are then functors where all of Things functions could be mapped except the transition functions.

With typeclasses I could create somthing like:

class ToA t where  
    toA :: t -> A Thing

Which seems cleaner still.

Are there other preferred approaches that would work in Haskell and PureScript?

like image 840
Mark Bolusmjak Avatar asked Aug 17 '15 21:08

Mark Bolusmjak


People also ask

What are the inputs and outputs of FSM?

In the FSM, the outputs, as well as the next state, are a present state and the input function. This means that the selection of the next state mainly depends on the input value and strength lead to more compound system performance.

How does state encoding affect the power consumption of a FSM?

We’ll see that, for a given state diagram, the state encoding method can reduce the power consumption of the FSM or increase its clock frequency. We can use a state diagram to represent the operation of a finite state machine (FSM). For example, consider the state diagram shown in Figure 1.

What do the lines between the states of the FSM mean?

The lines between these states show which transitions are possible between states and in which direction. These transitions have conditions for when the FSM needs to change between states.

What are the advantages of the Gray code in FSM?

With the Gray code, only one bit changes when moving between adjacent states. As a result, this encoding technique can reduce the power consumption of an FSM. Moreover, the Gray encoding makes the asynchronous outputs of an FSM resilient to glitches.


1 Answers

Here's a fairly simple way that uses a (potentially phantom) type parameter to track which state a Thing is in:

{-# LANGUAGE DataKinds, KindSignatures #-}
-- note: not exporting the constructors of Thing
module Thing (Thing, transAB, transAC, transCA) where

data State = A | B | C
data Thing (s :: State) = {- elided; can even be a data family instead -}

transAB :: Thing A -> Thing B
transAC :: Thing A -> Thing C
transCA :: Thing C -> Thing A

transAB = {- elided -}
transAC = {- elided -}
transCA = {- elided -}
like image 117
Daniel Wagner Avatar answered Sep 28 '22 03:09

Daniel Wagner