forked from kanaka/mal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
reducers.mal
32 lines (28 loc) · 952 Bytes
/
reducers.mal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
;; Left and right folds.
;; Left fold (f (.. (f (f init x1) x2) ..) xn)
(def! reduce
(fn* (f init xs)
;; f : Accumulator Element -> Accumulator
;; init : Accumulator
;; xs : sequence of Elements x1 x2 .. xn
;; return : Accumulator
(if (empty? xs)
init
(reduce f (f init (first xs)) (rest xs)))))
;; Right fold (f x1 (f x2 (.. (f xn init)) ..))
;; The natural implementation for `foldr` is not tail-recursive, and
;; the one based on `reduce` constructs many intermediate functions, so we
;; rely on efficient `nth` and `count`.
(def! foldr
(let* [
rec (fn* [f xs acc index]
(if (< index 0)
acc
(rec f xs (f (nth xs index) acc) (- index 1))))
]
(fn* [f init xs]
;; f : Element Accumulator -> Accumulator
;; init : Accumulator
;; xs : sequence of Elements x1 x2 .. xn
;; return : Accumulator
(rec f xs init (- (count xs) 1)))))