始终评估为t(或任何值)的函数

Mar*_*ark 3 lisp predicate common-lisp

比方说,我们想使用一个需要谓词的函数,但由于某种原因,我们对函数的其他功能(如:start:end参数)感兴趣,所以我们需要提供一个始终返回true的谓词.

显然,这根本不是问题:

CL-USER> (defparameter *list* '(0 1 2 3 4 5))
*LIST*
CL-USER> (remove-if (lambda (x) t) *list* :start 1 :end 3)
(0 3 4 5)
Run Code Online (Sandbox Code Playgroud)

工作,但根本不是很好.我们可能会得到一个丑陋的消息,x即不使用变量.因为我在美丽的LISP,我很好奇是否有一个'总是'的谓词?

我们可以定义它:

(defun tp (&rest rest)
  (declare (ignore rest))
  t)
Run Code Online (Sandbox Code Playgroud)

..但它可能存在吗?

Jos*_*lor 10

您正在寻找constantly带参数的函数并返回一个始终返回该值的函数.那么你需要的谓词是(constantly t).从而:

CL-USER> (remove-if (constantly t) '(0 1 2 3 4 5) :start 1 :end 3)
(0 3 4 5)
Run Code Online (Sandbox Code Playgroud)

这些说明constantly表明您与提议的实施完全一致.(尽管如此,你做的更好了(declare (ignore …)).)

笔记:

经常可以定义:

(defun constantly (object)
  #'(lambda (&rest arguments) object))
Run Code Online (Sandbox Code Playgroud)

写完之后,我发现这可能是重复的.我没有找到一个正确的副本,发现一个类似的,更具体的问题,想要删除一个位置的单个元素,是否有一个常见的lisp宏用于从列表中弹出第n个元素?,Rainer Joswig的答案包括:

删除列表的第n个元素:

(defun remove-nth (list n)
  (remove-if (constantly t) list :start n :end (1+ n)))
Run Code Online (Sandbox Code Playgroud)

这实际上只是该方法的一般化,因为您正在处理任意序列边界.因此我们可以(使边界参数类似于subseq's):

(defun remove-subseq (sequence &optional (start 0) end)
  (remove-if (constantly t) sequence :start start :end end))

(defun remove-nth (sequence n)
  (remove-subseq sequence n (1+ n)))
Run Code Online (Sandbox Code Playgroud)
CL-USER> (remove-subseq '(0 1 2 3 4 5) 1 3)
(0 3 4 5)
CL-USER> (remove-nth '(0 1 2 3 4 5) 3)
(0 1 2 4 5)
Run Code Online (Sandbox Code Playgroud)