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:
parent
499e41ec21
commit
d0ca46a2e4
11
core.mal
11
core.mal
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user