首页 > 解决方案 > 同时折叠和映射

问题描述

我有一个功能

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 )

并且需要getThing在 的列表上运行Thing,将 传递Model给每个调用getThing并返回模型和Cmd要在 a 中执行的所有 s Platform.Cmd.batch

我认为这个问题应该分解成多个部分,但我不知道从哪里开始。感觉像使用折叠是适合的Model,但我需要一张地图Cmd

标签: functional-programmingelm

解决方案


您只需要解压缩在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

这里的命名是非常具体的,以帮助助记符,但只需使用更通用的变量名就可以很容易地概括它。


推荐阅读