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?