Is encountering impossible state symptomatic of a bad model?

I built a small package for defining state machines in a more “formal” way in Elm, and there is a write up somewhere on here if I can find it again…

https://package.elm-lang.org/packages/the-sett/elm-state-machines/latest/

The package API itself does not reveal much about how to use it, but there is an example showing its intended usage: https://github.com/the-sett/elm-state-machines/blob/1.0.1/example/GameState.elm

I used this technique for a while, but eventually gave up. The reason being that it is a hassle to work this way. Usually during development a state machine will grow and be adjusted quite a bit, I don’t always have something fully designed ahead of time. Its just a lot simpler to work with a state machine as (Model, Msg) tuple and convenience won the argument.

1 Like

It can depend on your Model, but sometimes there is an obvious ‘partitioning’ of different Msgs between the different Model states, in which case a good way to minimise the negative effects of a catchall can be something like this:

type Model
    = FirstState StartingData
    | SecondState FollowupData
    | ThirdState FinalData

type Msg
    = First FirstStateMsg
    | Second SecondStateMsg
    | Third ThirdStateMsg

type FirstStateMsg
    = ...

type SecondStateMsg
    = ...

type ThirdStateMsg
    = ...

update : Msg -> Model -> Model
update anyMsg model =
    case ( anyMsg, model ) of
        ( First msg, FirstState data ) ->
            updateFirst msg data

        ( Second msg, SecondState data ) ->
            updateSecond msg data

        ( Third msg, ThirdState data ) ->
            updateThird msg data

        _ ->
            -- Stale message, ignore
            model

updateFirst : FirstStateMsg -> StartingData -> Model
updateFirst msg data =
    case msg of
        ...
        -- NO CATCHALL USED HERE

-- updateSecond, and updateThird similarly

This way you can ignore ‘stale’ Msgs with a catchall, but the compiler still has your back every time you add a new message (and makes sure you add code to deal with it) because there are no catchalls used in updateFirst, updateSecond etc.

2 Likes

Yes I see that, and it’s kinda bugging me actually :sweat_smile:

Awesome, this looks like a great resource - thanks!

Thanks, I’ll check it out.

Good to know.

This look like a great idea, thanks for the suggestion!

Some problems can’t be modeled in a way that eliminates all impossible states. Others technically can, but the representation is so clunky as to be unusable. This article explores the limits of modeling to avoid impossible states and when to blend it with other strategies.

5 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.