OCaml中的List.fold_left

时间:2013-01-16 16:27:38

标签: ocaml

我写了一个函数,它添加了给定列表中的所有元素:

let rec add = function []->0 | h::t->h+add(t);;

现在我想编写相同的函数,但使用List.fold_left,但我尝试了几次更改,但仍然有错误。首先我尝试了这个:

let rec add = function []->0 | h::t-> add List.fold_left((fun h t-> h+t) h t);;

但是我有一个错误,我注意到List.fold_left返回一个int值,所以递归是不必要的。所以我换了:

let add = function []->0 | h::t -> List.fold_left ( fun h t-> h+t h t);;

但我仍然收到错误类型的错误: Error: This expression has type int -> 'a -> 'b but an expression was expected of type 'a 但是我不知道如何解决这个问题,在这个例子中有人可以解释我如何使用List.fold_left吗?

3 个答案:

答案 0 :(得分:11)

fold_left通过应用函数并以特定方式累积结果,在列表上运行,作为函数执行。它会为您处理和摘要递归。它处理列表的结构,因此您可以处理如何以特定方式组合列表的元素。因此,您需要找出要应用于以相同方式在列表上运行的fold_left的高阶函数。

例如,以下是获取列表最大元素的两种方法,...

let rec max_list smallest lst = match lst with 
    | []   -> smallest
    | h::t -> max_list (max smallest h) t

let max_list smallest lst =
    List.fold_left (fun acc x -> max acc x) smallest lst

你会注意到功能的某些方面的相似性;基本情况(最小)以及如何组合元素(使用函数max)。您应该在函数中看到相同的相似之处。

回顾最终的实施,

let add = function | []->0
                   | h::t -> List.fold_left (fun h t-> h+t h t)

这里的问题是你有一个错位的括号......

let add = function | []->0
                   | h::t -> List.fold_left (fun h t-> h+t) h t

但这可以简化,类似于我上面的例子。

答案 1 :(得分:4)

添加整数列表的一种方法:

# List.fold_left (+) 0 [1; 3; 5; 7];;
- : int = 16

答案 2 :(得分:2)

如果使用Core.Std,则需要命名参数,例如,

List.fold_left ~f:(+) ~init:0 [1; 3; 5; 7];;
- : int = 16