List.fold_right
nie tail-recursive
jest wskazane tutaj http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.htmlDlaczego OCaml List.fold_right nie został zaimplementowany jako rekursywny?
Moje pytanie jest dlaczego List.fold_right
nie został wdrożony jako tail-recursive
?
myślę, że to nie jest trudne do zrobienia, więc
let rev l =
let rec revr acc = function
| [] -> acc
| hd::tl -> revr (hd::acc) tl
in
revr [] l;;
let fold_right f l b =
let rev_l = rev l
in
let rec folder_rr acc = function
| [] -> acc
| hd::tl -> folder_rr (f hd acc) tl
in
folder_rr b rev_l;;
Ja również znaleźć się w bibliotece, wiele funkcji nie tail-recursive
są natomiast mogą być realizowane jako tail-recursive
. W jaki sposób producent podejmował takie decyzje?
Czy są jakieś dowody, że wersje rekurencyjne ogona są wolniejsze? Nie jestem przekonany ... :-) –
Łatwym sposobem na uczynienie 'fold_right' tailurialnym, tak jak to miało miejsce w oryginalnym wpisie powyżej, jest najpierw odwrócenie listy, a następnie użycie fold_left. Koszt ten można łatwo zmierzyć na podstawie testów porównawczych. Dostępne są bardziej wyrafinowane techniki, takie jak użycie licznika wzdłuż zwykłego przejścia i tylko "rev" reszta listy dla złożenia w lewo, gdy licznik przechodzi przez tresholf; pozwala to na bardzo małe obciążenie dla małych list. Zaimplementowaliśmy to [w bateriach] (https://github.com/ocaml-batteries-team/batteries-included/blob/master/src/batList.ml#L380) i wydajność jest w porządku. – gasche