2013-04-20 2 views
0

Say есть функция F. Я хочу, чтобы передать список функций в качестве аргумента в функцию F.Передача списка функций в качестве аргумента в общей Lisp

Функции F будет проходить через каждую функцию в списке один за другим и применяют каждый из двух целых чисел: x и y соответственно.

Например, если список = (плюс, минус, плюс, деление, раз, плюс) и x = 6 и y = 2, результат будет выглядеть следующим образом:

8 4 8 3 12 8 

Как реализовать это в общем Lisp?

ответ

5

Есть много возможностей.

CL-USER> (defun f (x y functions) 
      (mapcar (lambda (function) (funcall function x y)) functions)) 
F 
CL-USER> (f 6 2 (list #'+ #'- #'+ #'/ #'* #'+)) 
(8 4 8 3 12 8) 
CL-USER> (defun f (x y functions) 
      (loop for function in functions 
       collect (funcall function x y))) 
F 
CL-USER> (f 6 2 (list #'+ #'- #'+ #'/ #'* #'+)) 
(8 4 8 3 12 8) 
CL-USER> (defun f (x y functions) 
      (cond ((null functions) '()) 
       (t (cons (funcall (car functions) x y) 
          (f x y (cdr functions)))))) 
F 
CL-USER> (f 6 2 (list #'+ #'- #'+ #'/ #'* #'+)) 
(8 4 8 3 12 8) 
CL-USER> (defun f (x y functions) 
      (labels ((rec (functions acc) 
         (cond ((null functions) acc) 
          (t (rec (cdr functions) 
            (cons (funcall (car functions) x y) 
              acc)))))) 
      (nreverse (rec functions (list))))) 
F 
CL-USER> (f 6 2 (list #'+ #'- #'+ #'/ #'* #'+)) 
(8 4 8 3 12 8) 
CL-USER> (defun f (x y functions) 
      (flet ((stepper (function result) 
        (cons (funcall function x y) result))) 
      (reduce #'stepper functions :from-end t :initial-value '()))) 
F 
CL-USER> (f 6 2 (list #'+ #'- #'+ #'/ #'* #'+)) 
(8 4 8 3 12 8) 

И так далее.

Первые два являются читаемыми, третье - это, вероятно, то, как это сделает новичок в первом курсе Лиспа, четвертый по-прежнему остается новичком, после того как он узнал о оптимизации хвостового вызова, пятый написан под обложкой Haskeller.

+1

Спасибо. Ваш ответ очень ценится. –

+0

Добро пожаловать. Вы можете нажать на полую стрелку слева от ответа, если хотите принять ответ. Также обратите внимание, что вы можете использовать 'if' вместо' cond', который был более или менее написан рефлексией. – danlei

Смежные вопросы