Elm-将Msg转换为Cmd Msg

Elm-将Msg转换为Cmd Msg,elm,elm-architecture,Elm,Elm Architecture,我正在尝试从开始修改一个简单的应用程序,首先更新模型,然后触发另一个更新 update msg model = case msg of MorePlease -> (model, getRandomGif model.topic) NewGif (Ok newUrl) -> ( { model | gifUrl = newUrl }, Cmd.none) NewGif (Err _) -> (model, Cm

我正在尝试从开始修改一个简单的应用程序,首先更新模型,然后触发另一个更新

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 )
所以我的Msg需要是Cmd-Msg类型。如何将“我的味精”转换为Cmd味精


注意:我知道有一种更简单的方法来进行此更改,但我试图从根本上理解Elm

实际上没有必要将
Msg
转换为
Cmd Msg
。请记住
update
只是一个函数,因此可以递归调用它

您的
NewTopic
案例处理程序可以简化为:

NewTopic NewTopic->
更新{model | topic=newTopic}
如果您真的希望Elm体系结构在这种情况下触发Cmd,您可以将
Cmd.none
map
映射到所需的
Msg

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

(实际上不推荐)

添加以下功能:

run:msg->Cmd msg
跑米=
Task.perform(始终为m)(Task.success())
然后,您的代码将变成:

NewTopic NewTopic->
({model | topic=newTopic},请运行更多)

谢谢。这是解决问题的一个更简单的方法。我仍然想知道,我是否需要“强制转换”“a
Msg
到a
Cmd Msg
?如果我这样做了,我会怎么做?@ChadGilbert:你能再详细说明一下为什么不推荐第二种方法,即启动新的
Msg
?返回
Cmd
将导致Elm架构生命周期的另一个周期,所以,你实际上只是花费额外的CPU周期,如果只是为了激发另一个味精,你不需要浪费这些。可能有一些原因需要强制执行另一个事件循环(如动画或其他视图更新,但即使是这些更新也需要额外的代码)。在大多数情况下,强制执行不必要的
Cmd
,IMO,感觉它缺少了
update
函数作为一个函数的基本性质,并且误解了事件周期。是否有可能通过
更多信息传递一些参数请
消息?是,任何导致
Msg
的内容都可以使用。例如,
Cmd.map(始终(SomethingElse param1 param2))Cmd.none
为您的答案提供解释。我的消息有一个参数,因此语法不同,但使用
Task.perform
在接受的答案中所示的
Cmd.map
不起作用时对我有效。