关于lisp:根据函数F从列表L中返回最好的元素?

returning the best element from the list L according to function F?

我正在尝试用 lisp 编写一个函数,它有 2 个参数,一个函数 F 和一个列表 L
如果我用 \\'> 代替 F 并且列表 L 是 \\'(1 2 3 4 5) 它将返回 5,因为 5 是最大的。
如果我们把 \\'< 然后它比较所有列表元素并给出最小的一个作为输出。 等等。

我们甚至可以将自定义编写函数代替 F 进行比较。
我希望我能提供更多示例代码,但我真的一开始就卡住了。

1
2
3
4
5
6
(DEFUN givex (F L)
(cond
    (F (car L) (car (cdr L))
    ;after this i got stuck  
)
)

另一个尝试编写这个函数

1
2
3
(defun best(F list)
    (if (null (rest list)) (first list)
    (funcall F (first List) (best (F list)))))


你快到了,只是 else 子句返回 f\\ 的返回值而不是 best 元素:

1
2
3
4
5
6
7
8
9
(defun best (F list)
  (let ((first (first list))
        (rest (rest list)))
    (if (null rest)
        first
        (let ((best (best f rest)))
          (if (funcall F first best)
              best
              first)))))

示例:

1
2
3
4
(best #'< '(1 2 3))
==> 3
(best #'> '(1 2 3))
==> 1

请注意,这种递归实现不是尾递归的,因此它不是最有效的。你可能更喜欢这个:

1
2
(defun best (f list)
  (reduce (lambda (a b) (if (funcall f a b) b a)) list))

或者,更好的是,

1
2
3
4
5
6
7
8
9
(defmacro fmax (f)
  `(lambda (a b) (if (,f a b) b a)))

(reduce (fmax <) '(1 2 3))
==> 1
(reduce (fmax >) '(1 -2 3 -4) :key #'abs)
==> 1
(reduce (fmax <) '(1 -2 3 -4) :key #'abs)
==> 4