You can just use the classic temporal logic approach, where state is passed explicitly as a parameter and the new state is returned.
This is what state monads are doing anyway under a hidden syntax, and for simple cases it may be easier that building a full dedicated monad.