在OCaml中,典型的折叠功能如下:
let rec fold (combine: 'a -> 'b -> 'b) (base: 'b) (l: 'a list) : 'b =
begin match l with
| [] -> base
| x :: xs -> combine x (fold combine base xs)
end
对于熟悉OCaml的人(与我不同),它的作用应该非常简单。
我正在编写一个函数,当列表中的所有项目都满足条件时返回true:如果条件x对于某个列表l中的所有x都为true。但是,我正在使用fold函数实现该函数,并且遇到了麻烦。具体来说,我不知道列表应该返回什么。我知道理想情况下应将条件应用于列表中的每个项目,但我不知道语法应如何显示。 x && acc
可以使用,但无法通过非常简单的测试(如下所示)
let test () : bool =
not (for_all (fun x -> x > 0) [1; 2; -5; -33; 2])
;; run_test "for_all: multiple elements; returns false" test
这是我的初步尝试。任何帮助表示赞赏:
let for_all (pred: 'a -> bool) (l: 'a list) : bool =
fold (fun(x:'a)(acc: bool)-> _?_&&_?_ )false l
答案 0 :(得分:2)
let rec fold (combine: 'a -> 'b -> 'b) (base: 'b) (l: 'a list) : 'b =
match l with
| [] -> base
| x::xs -> combine x (fold combine base xs)
let for_all (pred: 'a -> bool) (lst: 'a list) =
let combine x accum =
(pred x) && accum
in
fold combine true lst
您的Combine函数不应执行x && base
,因为列表中的元素通常不是bool
。您希望您的谓词函数首先将元素评估为bool,然后使用累加器对其进行“和”处理。
begin
中不需要end
和fold
。您可以仅使用match <identifier> with
进行模式匹配。
fold
有两种广泛的类型:fold_left
和fold_right
。您正在使用fold_right
,基本上,它会遍历整个列表,并开始从列表末尾开始“组合”。这不是tail-recursive。
fold_left
从列表的最前面开始,并立即将每个元素与累加器组合在一起。这不会通过大量的递归函数调用“吞噬”您的堆栈。