List.fold_right
ist nicht tail-recursive
wie hier angegeben http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.htmlWarum wurde OCaml List.fold_right nicht als Tail-Recursive implementiert?
Meine Frage, warum List.fold_right
nicht als tail-recursive
umgesetzt wurde?
Ich denke, es ist nicht schwer zu tun, so
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;;
ich auch in der Bibliothek gefunden, eine Reihe von Funktionen sind nicht tail-recursive
, während sie als tail-recursive
umgesetzt werden können. Wie hat der Hersteller solche Entscheidungen getroffen?
Haben Sie irgendwelche Beweise, dass tail rekursive Versionen langsamer sind? Ich bin nicht überzeugt ... :-) –
Der einfache Weg, 'falt_right' tail-recursive zu machen, wie es im ursprünglichen Post oben gemacht wurde, besteht darin, die Liste zuerst umzukehren und dann fold_left zu verwenden. Dies hat Kosten, die an Benchmarks leicht gemessen werden können. Es sind verfeinerte Techniken verfügbar, wie zum Beispiel die Verwendung eines Zählers neben dem üblichen Durchlauf und nur das "Aufdrehen" des Rests der Liste für die Fold-Links, wenn der Zähler einen Schwellenwert überschreitet; Dies ermöglicht einen sehr geringen Overhead für kleine Listen. Wir haben dies [in Batterien] implementiert (https://github.com/ocaml-batteries-team/batteries-included/blob/master/src/batList.ml#L380) und die Leistung ist in Ordnung. – gasche