On Lisp復習

5.4 関数を合成する

CL-USER 1 > 
(defun compose (&rest fns)
  (if fns
      (let ((fn1 (car (last fns)))
            (rest (butlast fns)) )
        #'(lambda (&rest args)
            (reduce #'funcall rest
                    :from-end t
                    :initial-value (apply fn1 args) )))
    #'identity))
COMPOSE

CL-USER 2 > (funcall (compose #'(lambda (x) (* x 10)) #'1+ #'find-if) #'evenp '(1 2 3))
30

CL-USER 3 > 
(defun my-complement (pred)
  (compose #'not pred) )
MY-COMPLEMENT

CL-USER 4 > (funcall (my-complement #'evenp) 3)
T
CL-USER 5 > 
(defun fint (fn &rest fns)
  (if (null fns)
      fn
    (let ((chain (apply #'fint fns)))
      #'(lambda (x)
          (and (funcall fn x) (funcall chain x)) ))))
FINT

CL-USER 6 > (find-if (fint #'plusp #'evenp) '(-2 -1 0 1 2))
2