Hi, I’m learning OCaml and I wanted to model some sort of finite state machine with static checking of possible state transitions.
I started with variants, trying to code it like this:
type stopwatch = | Running of int | Paused of int let start = Running 0 let tick (Running s) = Running (s + 1) let pause (Running s) = Paused s let resume (Paused s) = Running s let sw = start |> tick |> pause |> tick
I expect that last line will fail with compiler error because you shouldn’t be able to tick on paused stopwatch. But it compiles without errors.
Then I discovered polymorphic variants and used it instead:
type stopwatch = [ | `Running of int | `Paused of int ] let start = `Running 0 let tick (`Running s) = `Running (s + 1) let pause (`Running s) = `Paused s let resume (`Paused s) = `Running s let sw = start |> tick |> pause |> tick
This time compiler works as I expected:
Error: This expression has type [< `Running of int ] -> [> `Running of int ] but an expression was expected of type [> `Paused of int ] -> 'a The first variant type does not allow tag(s) `Paused
Is it ok to use polymorphic variants here or do I need to do something more with the first example?