懒惰列表的好`partition`实现?

时间:2015-12-10 10:08:21

标签: ocaml

type 'a lazy_list_t = Cons of 'a * (unit -> 'a lazy_list_t)

实施partition功能的最佳/有效方式是什么?

这是我的实施。

let rec filter f (Cons (x, tl_f)) =
  if f x then Cons (x, fun () -> filter f (tl_f()))
  else filter f (tl_f())

let partition f ll = filter f ll, filter (fun x -> f x |> not) ll

我认为阅读起来很简单,但缺点是每个元素,f实际应用了两次。

有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

我会这样做:

let rec fold_right f ll b =
  match ll with
    [] -> b
  | x :: xs -> f x (fold_right f xs b);;

let partition f ll = 
  let f_split v (tt, ff) = 
    if f v = true then (v::tt,ff) else (tt,v::ff) in 
    fold_right f_split ll ([], []);; 

这样你就可以写下一个懒惰的fold_right并最终写下一个懒惰的分区函数。 例如某种类似的东西:

let rec fold_right f (Cons(x, xs)) b =
  f x (fold_right f (xs()) b);;