2015-12-10 85 views
2
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實際上應用了兩次。

有沒有更好的辦法?

+0

你可以'map'在列表上得到'[(F V,V),..]'然後用'filter'兩倍以上這一點。這將只對每個元素應用「f」一次。 –

+0

@DanD。好想法。你能否擴大你的評論回答,以便我可以標記爲正確的。 –

回答

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);; 
+0

你能否爲懶惰分區函數編寫代碼? –