This program behaves a little strange to my thinking:
https://ellie-app.com/96fMBHvP2a1/0
Its behaviour is driven by this simple update loop:
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case (Debug.log "update" msg) of
Count val ->
if model.count < 10 then
( { model | count = val }, message <| Count (val + 1) )
else
( model, Cmd.none )
The function message is:
message : msg -> Cmd msg
message x =
Task.perform identity (Task.succeed x)
And it prints the correct answer to the DOM – 10.
However, look at the console and see what is logged:
...
update: Count 10
update: Count 11
This means the update function is run 1 time more than I would expect. On Count 10 the else branch is followed, and Cmd.none is returned. But a Count 11 is still run.
Do both of a set of if and else branches get eagerly evaluated in Elm?
Does calling Task.perform immediately evaluate, rather than return a Cmd which uses a continuation to invoke the next update loop more asynchronously?
The behaviour of the above code suggests that the answer is yes to both of these questions, and I find that a little surprising.