1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-11 13:55:55 +03:00

core.mal: give foldr a tail recursive definition

This commit is contained in:
Nicolas Boulenguez 2019-05-15 00:07:58 +02:00
parent 499e41ec21
commit d0ca46a2e4

View File

@ -21,16 +21,19 @@
(reduce f (f init (first xs)) (rest xs)))))
;; Right fold (f x1 (f x2 (.. (f xn init)) ..))
;; `foldr` is not tail-recursive. `reduce` must be preferred for big lists.
;; The natural implementation for `foldr` is not tail-recursive, so we
;; rely on efficient `nth` and `count`.
(def! foldr
(fn* [f init xs]
;; f : Element Accumulator -> Accumulator
;; init : Accumulator
;; xs : sequence of Elements x1 x2 .. xn
;; return : Accumulator
(if (empty? xs)
init
(f (first xs) (foldr f init (rest xs))))))
(let* [rec (fn* [acc index]
(if (< index 0)
acc
(rec (f (nth xs index) acc) (dec index))))]
(rec init (dec (count xs))))))
;; Returns the unchanged argument.
(def! identity (fn* (x) x))