web-dev-qa-db-ja.com

Elm-MsgをCmdMsgに変換します

Elm-langチュートリアル から単純なアプリを変更して、最初にモデルを更新してから、別の更新をトリガーしようとしています。

update msg model =
  case msg of
    MorePlease ->
      (model, getRandomGif model.topic)

    NewGif (Ok newUrl) ->
      ( { model | gifUrl = newUrl }, Cmd.none)

    NewGif (Err _) ->
      (model, Cmd.none)

    -- my addition
    NewTopic newTopic ->
      ({ model | topic = newTopic}, MorePlease)

NewTopicブランチが原因で、これはコンパイラで失敗します。

The 3rd branch has this type:

( { gifUrl : String, topic : String }, Cmd Msg )

But the 4th is:

( { gifUrl : String, topic : String }, Msg )

したがって、私のメッセージはCmdMsgと入力する必要があります。メッセージをCmdメッセージに変換するにはどうすればよいですか?

注:この変更を行うためのより簡単な方法があることは認識していますが、私はElmをより根本的に理解しようとしています

16
steel

MsgCmd Msgに変える必要は本当にありません。 updateは単なる関数であるため、再帰的に呼び出すことができます。

NewTopicケースハンドラーは次のように簡略化できます。

NewTopic newTopic ->
    update MorePlease { model | topic = newTopic}

このシナリオでElmアーキテクチャがCmdを起動することを本当に望んでいる場合は、Cmd.noneの単純なmapを目的のMsgに対して実行できます。

NewTopic newTopic ->
    ({ model | topic = newTopic}, Cmd.map (always MorePlease) Cmd.none)

(実際には推奨されません)

24
Chad Gilbert

次の関数を追加します。

run : msg -> Cmd msg
run m =
    Task.perform (always m) (Task.succeed ())

コードは次のようになります。

NewTopic newTopic ->
      ({ model | topic = newTopic}, run MorePlease)
4
Deimos