我只想使用 List.fold_left 将我的 add1 函数应用于此列表 [1,2,3]
我的 add1 函数应该只为每个元素加 1,所以我会得到 [2, 3, 4]
我做这个练习的主要目标只是试验 List.fold_left。我实际上并不关心加 1,我只是选择该函数,因为它看起来很容易编写(我是 ocaml 初学者)。
我的最终目标实际上是使用 List.fold_left 和已在其他地方编写的函数填充空 StringMap 的键,因此如果有人对此有深入了解,我们将不胜感激
这是第一次尝试(我尝试了两次)
let rec add1 = function
| [] -> []
| h::t -> (h+1)::(add1 t) in List.fold_left add1 [1, 2, 3];;
这是第二次尝试
let a(b) =
let rec add1 = function
| [] -> []
| h::t -> (h+1)::(add1 t)
in
let c = List.fold_left add1 b
in a [1,2,3];;
我认为你应该从:
开始let add x = x + 1
然后构建一个函数,通过 List.fold_left 将函数应用于列表:
let apply_f_to_list_elements fn lst = (*use List.fold_left here*)
您确定要 List.fold_left 而不是 List.map 吗?
它可能会帮助您了解如何实施
fold_left
。
let rec fold_left f init lst =
match lst with
| [] -> init
| x::xs -> fold_left f (f init x) xs
因此,考虑一下当像 sum 函数这样的函数以
fold_left
的形式实现时,会发生什么。
let sum lst =
fold_left (+) 0 lst
如果我们评估
sum [1; 2; 3; 4]
:
sum [1; 2; 3; 4]
fold_left (+) 0 [1; 2; 3; 4]
fold_left (+) (0 + 1) [2; 3; 4]
fold_left (+) (1 + 2) [3; 4]
fold_left (+) (3 + 3) [4]
fold_left (+) (6 + 4) []
10
我们可以用
map
来定义 fold_left
:
let map f lst =
let f' init x = f x :: init in
fold_left f' [] lst
我们来评价一下
map (fun x -> x + 1) [5; 2; 6]
:
map (fun x -> x + 1) [5; 2; 6]
fold_left f' [] [5; 2; 6]
fold_left f' (5 + 1 :: []) [2; 6]
fold_left f' (2 + 1 :: [6]) [6]
fold_left f' (6 + 1 :: [3; 6]) []
[7; 3; 6]
现在,由于我们解构和创建列表的方式,结果是相反的。我们可以通过反转结果列表来克服这个问题。
fold_left
或使用
let map f lst =
let f' init x = f x :: init in
let lst' = fold_left f' [] lst in
List.rev lst'
运算符:
|>
将其提升到新的水平
let map f lst =
let f' init x = f x :: init in
let |> fold_left f' [] |> List.rev
将列表和累加器中的第一个元素转换为下一次迭代的累加器。如果您想将此概念应用到您的
fold_left
模块,请考虑 StringMap
生成一个空的 StringMap.empty
,以及 StringMap.t
接受 key、关联的 value 和现有映射,并返回添加了映射的新地图。 您可以轻松地使用
StringMap.add
将一张最初为空的地图逐步构建为完整的地图。剩下的唯一问题是您选择与列表中的每个字符串关联的值。
fold_left
和
map
我认为这句话可以帮助您理解差异:
想象一下你和很多人一起吃一顿丰盛的晚餐。你正在上菜:你遍历所有的人,然后用装有食物的盘子替换他们的空盘子。这是一个地图操作:桌子上的盘子数量没有改变,但是对于每个盘子,你都做了相同的操作(改变盘子的内容)。
一切完成后,你收集所有脏盘子:这是一个折叠操作,最后,桌子上不再有盘子,但你已经对每个盘子做了一些事情(堆叠它们)并返回文件结果(a一堆脏盘子)。
在这两种情况下,都会系统地应用操作。不同之处在于,Map 保留了当前的“结构”(桌子上的盘子),而 Fold 则删除了结构,并构建了其他东西。”