data FSM state input output = FSM -- Input and output alphabet are constricted at compile time by datatype { start :: state, -- Start state trans :: state -> input -> state, -- Transition function accept :: [state], -- Set of accept states out :: OutFunc state input output -- Output function, either Moore or Mealy } data OutFunc state input output = Moore (state -> output) | Mealy (state -> input -> output) runFSM :: Eq state => FSM state input output -> [input] -> (state, Bool) runFSM (FSM start trans accept out) inputs = (finalState, elem finalState accept) where -- finalState = foldl' trans start input finalState = go inputs start -- Output only changes when state changes occur --go :: [input] -> state -> state go [] acc = acc go (x : xs) currentState = go xs (trans currentState x) data Binary = Zero | One deriving (Enum, Eq, Show) data EvenState = E0 | E1 deriving (Eq, Show) isEven :: FSM EvenState Binary () isEven = FSM { start = E0 , trans = trans , accept = [E0] , out = Moore $ const () } where trans :: EvenState -> Binary -> EvenState trans E0 _ = E1 trans E1 _ = E0