2011-07-19 34 views
3

我尝试List.fold_left要经过一个列表xl,我想,当某些条件满足时退出迭代:如何退出OCaml的迭代?

List.fold_left 
    (fun x acc -> 
    if x = 5 then STOP THE ITERATION 
    else x + acc) 
xl 

谁能告诉我该如何表达STOP THE ITERATION这里?谢谢

EDIT1:通过上面的代码,我想说,直到我们见面的第5我们不阻止积累。

回答

7

对于其余的调用,您无法使用内置折叠功能进行此操作,而没有发生异常,或者在累加器中标记了一些无操作符 - 因为phimuemue提及。或者,你可以只写一个非常简单的尾递归函数及早采取回国照顾,

(** Fold left on a list with function [f] until predicate [p] is satisfied **) 
let rec fold_until f p acc = function 
    | x :: xs when p x -> acc 
    | x :: xs -> fold_until f p (f acc x) xs 
    | [] -> acc 

let accum_until_five = 
    fold_until (fun acc x -> x + acc) (fun x -> x = 5) 0 
3

因此,你必须条件编码到你的内部函数的参数x

let t l = 
    let (a,b) = 
     List.fold_left 
      (fun ((accx, condition) as acc) x -> 
       if condition then acc else (x+accx, x=5)) 
      (0,false) l 
    in 
    a;; 

也就是说,你要告诉你的功能 - 一旦5已经看到 - 它应该只需返回到目前为止完成的工作。

0

有几种方法。

要么你添加一个标志,告诉它在遇到5时停止总结,或者先过滤列表或者编写自己的折叠。他们三人都很容易实施。

编辑:上面提供的额外参数可能是最简单的,你自己的折叠可能是最快的。

你也可以使用异常过早地逃脱,但这更多的是黑客攻击。

+2

我不认为例外是在这种情况下,黑客,或在一般情况下,本地异常点的一部分是这样的事情。 – nlucaroni