The main difference between gen_statem and the older gen_fsm, is the addition of a new “handle event function” callback mode, with less restrictions on the state data type.
Converting an existing state machine, is pretty easy. Change the callback mode, and move the existing state functions into one callback:
callback_mode() -> handle_event_function. handle_event({call, From}, get_balance, open, #{balance:=Balance} = Data) -> {keep_state, Data, [{reply, From, Balance}]}; handle_event({call, From}, close, open, Data) -> {next_state, closed, Data, [{reply, From, closed}]}; handle_event({call, From}, {deposit, Amount}, open, #{balance:=Balance} = Data) when is_number(Amount) andalso Amount > 0 -> NewBalance = Balance + Amount, {keep_state, Data#{balance:=NewBalance}, [{reply, From, deposit_made}]}; handle_event({call, From}, {withdraw, Amount}, open, #{balance:=Balance} = Data) when is_number(Amount) andalso (Balance - Amount > 0) -> NewBalance = Balance - Amount, {keep_state, Data#{balance:=NewBalance}, [{reply, From, withdrawal_made}]}; handle_event({call, From}, reopen, closed, Data) -> {next_state, open, Data, [{reply, From, open}]}.
Whether you prefer this style, or the previous version, seems like a matter of personal taste, if you don’t need the extra flexibility.