aboutsummaryrefslogtreecommitdiff
path: root/hofs.lisp
blob: e8bdbc42dd2ba56507119e1b29d907bbc9596a72 (plain)
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
33
34
35
36
37
38
;;; hofs.lisp -- higher-order functions

(in-package :lambda-riffs)

(defun lambda-if (pred then &optional (else (constantly nil)))
  "Returns a function that applies PRED and conditionally executes
THEN when PRED returned non-nil or otherwise executes ELSE.  Each of
PRED, THEN, and ELSE are  assumed to accept the same arguments."
  (lambda (&rest args)
    (if (apply pred args)
        (apply then args)
        (apply else args))))

(defun lambda-cond (&rest pairs)
  "PAIRS is a list: PRED1 F1 PRED2 F2 ...
   Returns a function that applies FN to the argumetns for the first N
   such that PREDN returns non-nil.  Each of the PREDN and FN are
   assumed to accept the same arguments."
  (lambda (&rest args)
    (loop for (pred fn . more) on pairs by #'cddr
          when (apply pred args)
            return (apply fn args))))

(defun mapped  (fn1 &rest fns)
  "Return a function the arguments of which are applied to (FN1 . FNS),
returning a list of return values."
  (lambda (&rest args)
    (loop :for fn :in (cons fn1 fns)
          :collect (apply fn args))))


(defun rev (fn)
  "Return a function that applies its arguments to FN in reverse order.

E.g. (funcall (rev #'cons) 1 2)  ;; (2 . 1)"
  (lambda (&rest args)
    (apply fn (reverse args))))