Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell infinite types and my FSM function

Tags:

types

haskell

I've just come across the "infinite type" in Haskell when I was attempting to write a finite state machine. I thought the following was very intuitive:

fsm []     _     acc = Right acc
fsm (x:xs) state acc =
    case state acc x of
        Left err     -> Left err
        Right (s, a) -> fsm xs s a

I give the state function the current state (the accumulator) and the new event, and the state function produces the next state function along with the new accumulator. I recurse until I have no more events.

The compiler tells me:

Occurs check: cannot construct the infinite type:
  t1 = b0 -> t0 -> Either a0 (t1, b0)
In the second argument of `fsm', namely `s'

Because state is now an infinite type. How to I rearrange this to make it work?

like image 446
Ana Avatar asked Dec 26 '11 21:12

Ana


1 Answers

Infinite types like this wreak havoc with the type system; they don't make it unsafe, but they cause a great deal of programs to type which you don't really want to, thus hiding errors, and I believe they make type inference harder too.

Thankfully, the solution is simple: you just need to make a newtype wrapper. data and newtype declarations are of course allowed to be recursive (otherwise, we couldn't even define lists!); it's just plain, unwrapped types which aren't.

newtype FSMState err acc ev =
    FSMState { stepFSM :: acc -> ev -> Either err (FSMState err acc ev, acc) }

fsm :: [ev] -> FSMState err acc ev -> acc -> Either err acc
fsm []     _     acc = Right acc
fsm (x:xs) state acc =
    case stepFSM state acc x of
        Left err     -> Left err
        Right (s, a) -> fsm xs s a
like image 55
ehird Avatar answered Nov 12 '22 12:11

ehird