カリー化関数
ふと思い立って、カリー化を行う関数を書いてみた。
(defun curry (fn &rest args) (lambda (&rest rest-args) (apply fn (append args rest-args)))) ;;; > (curry #'cons :first) -->#<CLOSURE (LAMBDA (&REST REST-ARGS)) {B3BC96D}> > (funcall * :second) --> (:FIRST . :SECOND)
カリー化関数は他の誰かも書いているだろうと思って調べて見たら、『The Common Lisp Cookbook - Functions』というページで、(宣言を除けば)全く同じ定義の関数を見つけて、少し面白かった。
追記: シンタックスシュガー
書きやすくするために、(極めて)簡単なリードマクロを定義してみる。
;; [fn arg1 arg2 ...] -> (funcall fn arg1 arg2 ...) (defun |[-reader| (stream arg) (declare (ignore arg)) `(funcall ,@(read-delimited-list #\] stream t))) (set-macro-character #\[ #'|[-reader|) (set-macro-character #\] (get-macro-character #\) nil)) ;; {fn-name arg1 arg2 ..} -> (curry #'fn-name arg1 arg2 ...) (defun |{-reader| (stream arg) (declare (ignore arg)) (destructuring-bind (fn . args) (read-delimited-list #\} stream t) `(curry #',fn ,@args))) (set-macro-character #\{ #'|{-reader|) (set-macro-character #\} (get-macro-character #\) nil)) ;;;; ;;;; > [{cons :first} :second] --> (:FIRST . :SECOND) > (mapcar {+ 10} '(1 2 3)) --> (11 12 13)
前よりそれっぽくなったような気がする。