branch: externals/dash
commit d94808670f673a7d2861a0ceb6caa6a045e3e67e
Author: Matus Goljer <[email protected]>
Commit: Matus Goljer <[email protected]>
Add -iteratefn
---
README.md | 22 ++++++++++++++++++++++
dash-functional.el | 17 ++++++++++++++++-
dev/examples.el | 13 +++++++++++++
3 files changed, 51 insertions(+), 1 deletions(-)
diff --git a/README.md b/README.md
index ac54f94..1af9122 100644
--- a/README.md
+++ b/README.md
@@ -198,6 +198,7 @@ These combinators require Emacs 24 for its lexical scope.
So they are offered in
* [-not](#-not-pred) `(pred)`
* [-orfn](#-orfn-rest-preds) `(&rest preds)`
* [-andfn](#-andfn-rest-preds) `(&rest preds)`
+* [-iteratefn](#-iteratefn-fn-n) `(fn n)`
## Anaphoric functions
@@ -1665,6 +1666,27 @@ In types: [a -> Bool] -> a -> Bool
(-filter (-andfn (-not 'even?) (-cut >= 5 <>)) '(1 2 3 4 5 6 7 8 9 10)) ;; =>
'(1 3 5)
```
+#### -iteratefn `(fn n)`
+
+Return a function `fn` composed `n` times with itself.
+
+`fn` is a unary function. If you need to use a function of higher
+arity, use `-applify` first to turn it into an unary function.
+
+With n = 0, this acts as identity function.
+
+In types: (a -> a) -> Int -> a -> a.
+
+This function satisfies the following law:
+
+ (funcall (-iteratefn fn n) init) = (-last-item (-iterate fn init (1+ n))).
+
+```cl
+(funcall (-iteratefn (lambda (x) (* x x)) 3) 2) ;; => 256
+(funcall (-iteratefn '1+ 3) 1) ;; => 4
+(funcall (-iteratefn 'cdr 3) '(1 2 3 4 5)) ;; => '(4 5)
+```
+
## Contribute
diff --git a/dash-functional.el b/dash-functional.el
index 4a00720..bd77519 100644
--- a/dash-functional.el
+++ b/dash-functional.el
@@ -60,7 +60,7 @@ each fn to the result of applying the previous fn to
the arguments (right-to-left)."
(lambda (&rest args)
(car (-reduce-r-from (lambda (fn xs) (list (apply fn xs)))
- args fns))))
+ args fns))))
(defun -applify (fn)
"Changes an n-arity function FN to a 1-arity function that
@@ -120,6 +120,21 @@ PREDS returns non-nil on x.
In types: [a -> Bool] -> a -> Bool"
(lambda (x) (-all? (-cut funcall <> x) preds)))
+(defun -iteratefn (fn n)
+ "Return a function FN composed N times with itself.
+
+FN is a unary function. If you need to use a function of higher
+arity, use `-applify' first to turn it into an unary function.
+
+With n = 0, this acts as identity function.
+
+In types: (a -> a) -> Int -> a -> a.
+
+This function satisfies the following law:
+
+ (funcall (-iteratefn fn n) init) = (-last-item (-iterate fn init (1+ n)))."
+ (lambda (x) (--dotimes n (setq x (funcall fn x))) x))
+
(provide 'dash-functional)
;;; dash-functional.el ends here
diff --git a/dev/examples.el b/dev/examples.el
index aabd343..220e846 100644
--- a/dev/examples.el
+++ b/dev/examples.el
@@ -712,4 +712,17 @@
(funcall (-andfn (-cut < <> 10) 'even?) 6) => t
(funcall (-andfn (-cut < <> 10) 'even?) 12) => nil
(-filter (-andfn (-not 'even?) (-cut >= 5 <>)) '(1 2 3 4 5 6 7 8 9 10))
=> '(1 3 5))
+
+ (defexamples -iteratefn
+ (funcall (-iteratefn (lambda (x) (* x x)) 3) 2) => 256
+ (funcall (-iteratefn '1+ 3) 1) => 4
+ (funcall (-iteratefn 'cdr 3) '(1 2 3 4 5)) => '(4 5)
+ (let ((init '(1 2 3 4 5))
+ (fn 'cdr))
+ (and (equal (funcall (-iteratefn fn 0) init)
+ (-last-item (-iterate fn init (1+ 0))))
+ (equal (funcall (-iteratefn fn 3) init)
+ (-last-item (-iterate fn init (1+ 3))))
+ (equal (funcall (-iteratefn fn 5) init)
+ (-last-item (-iterate fn init (1+ 5)))))))
))