同时折叠和贴图

Fold and map at the same time

我有一个功能

f : a -> b -> ( a, c )

我需要将 f 应用到 b 的列表,同时 a 被累积并且 c 被附加到列表,得到 ( a, List c ).我想我想做的签名是

(a -> b -> ( a, c )) -> a -> List b -> ( a, List c )

这里的真实场景是我有

getThing : Model -> Thing -> ( Model, Cmd Msg )

并且需要 运行 getThingThing 的列表中,将 Model 传递给对 getThing 的每次调用并返回模型和所有Cmd 将在 Platform.Cmd.batch.

中执行

我认为这个问题应该分解成多个部分,但我不确定从哪里开始。 Model感觉用fold比较合适,但是Cmd部分需要贴图

您只需要在折叠的每次迭代中解压由 getThing 返回的元组,然后将其作为累加器添加到累积的命令列表中的命令将其打包。

mapThings : (a -> b -> ( a, c )) -> a -> List b -> ( a, List c )
mapThings getThing initialModel things =
    List.foldl
        (\thing ( model, cmds ) ->
            let
                ( newModel, cmd ) =
                    getThing model thing
            in
            ( newModel, cmd :: cmds )
        )
        ( initialModel, [] )
        things

这里的命名非常具体,有助于助记,但只要使用更通用的变量名,就可以很容易地进行概括。

如果您不介意引入另一个包,还有 elm-community/list-extra List.Extra.mapAccuml 和 List.Extra.mapAccumr

https://package.elm-lang.org/packages/elm-community/list-extra/latest/List-Extra#mapAccuml