2013-01-16 31 views
1

我写了一个函数,该函数将所有元素从给定的清单:List.fold_left 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

回答

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 

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

4

一种方式加起来的整数列表:

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

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

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