2017-01-21 23 views
3

fold_right給出了從列表尾部開始的值,但是我想給fold_right一個函數作爲參數,這樣該函數將從列表的頭部開始收集值。 我想要iter接收從列表頭開始的值。在Ocaml中使用fold_right迭代

連續型傳是關鍵字...。另一個辦法要問的問題是如何fold_leftfold_right

let fold f ls acc = List.fold_right f ls acc 

val iter : ('a -> unit) -> 'a t -> unit 

let iter f my_type = 
    let rec iiter my_type return = 
     return (fold (fun x y -> f x) my_type())() in iiter my_type (fun x y ->()) 

但是,當我打電話:

iter (fun a -> print_string a) ["hi";"how";"are";"you"];; 

輸出:

youarehowhi

我需要

hihowareyou

回答

1
let fold_left f init ls = 
     let res = List.fold_right (fun a b acc -> b (f acc a)) ls (fun a -> a) 
     in res init 

現在呼籲

fold_left (fun a b -> Printf.printf "%s\n" b)() ["how";"are";"you"];;

給我們

如何

1

這很簡單,你必須嘗試匹配的簽名行爲。

迭代沒有輸入,並返回unit,而摺疊需要輸入並返回相同類型的輸出。現在,如果摺疊輸入爲unit,那麼您將擁有摺疊功能,該功能通過傳遞附加的unit並返回基本上對應於正常迭代的unit來對集合的每個元素應用函數,例如:

# let foo = [1;2;3;4;5];; 
# List.fold_left (fun _ a -> print_int a;())() foo;; 
12345- : unit =() 

正如你所看到的fold函數只是忽略第一個參數,總是返回unit

+0

我不允許fold_left使用:),否則我會已經做了,我必須只能使用fold_right和從頭開始迭代,而不是尾 – Oleg

+0

@Oleg:左褶可以用右褶實現,反之亦然;看看[這個Haskell文章](https://wiki.haskell.org/Foldl_as_foldr)(注意:foldr的參數順序在Haskell和OCaml之間是不同的) – newacct

+0

@newacct 我也想問一下,如果我上面的問題是可以理解的 – Oleg

1

在這種情況下,需要通過fold的延續是一個函數,一旦調用,它將遍歷列表的其餘部分。

編輯:像這樣:

let iter f list = fold 
    (fun head iter_tail -> (fun() -> f head;; iter_tail())) 
    list 
() 
+0

我只是沒有看到....,你能舉個例子嗎? – Oleg

1

fold_left就像List.fold_left但List.fold_right構造(未尾遞歸):

let fold_left f a l = List.fold_right (fun b a -> f a b) (List.rev l) a ;; 

是不是一個好主意,因爲fold_left不是尾遞歸的,List.fold_left是尾遞歸的。最好生成一個fold_right(尾遞歸)爲:

let fold_right f l a = List.fold_left (fun a b -> f b a) a (List.rev l) ;; 

如果你不能使用List。轉:

let rev l = 
    let rec aux acc = function 
    | [] -> acc 
    | a::tl -> aux (a::acc) tl 
    in 
    aux [] l 
;; 

ITER使用fold_left:

let iter f op = ignore (fold_left (fun a b -> f b;a) [] op) ;; 

測試:

# fold_left (fun a b -> (int_of_string b)::a) [] ["1";"3"];; 
- : int list = [3; 1] 
# rev [1;2;3];; 
- : int list = [3; 2; 1] 
# iter print_string ["hi";"how";"are";"you"];; 
hihowareyou- : unit =() 
+0

嗨,感謝您的回答,但我不允許使用List.rev – Oleg

+0

@Oleg。我在回覆中增加了修改(這不難寫)。祝你有美好的一天。 –

+0

謝謝你的回答,我也加了我的版本。 – Oleg