是否有任何标准函数可以通过应用于单个值来遍历谓词?

Are there any standard functions to iterate across predicates by applying to single value?

总是有很多函数可以遍历值列表,例如 mapcareverysome

我需要对单个值进行谓词迭代:

(let ( (val (complex-expr ...)) )
   (or (pred1 val) (pred2 val) ... (predN val)))

(let ( (val (complex-expr ...)) )
   (and (pred1 val) (pred2 val) ... (predN val)))

是否有任何标准函数使用以下语法执行上述代码:

(some-p val pred1 pred2 ... predN)
(every-p val pred1 pred2 ... predN)

更新 仅供参考 Elisp have this function in it's standard library:

run-hook-with-args-until-success
run-hook-with-args-until-failure
run-hook-with-args

该标准不包括与您要求的完全相同的任何内容,但它确实包括 someevery 用于计算(或(f x1)(f x2)…(f xn))(和(f x1)(f x2)…(f xn)):

CL-USER> (some 'evenp '(1 2 3 4 5))
T
CL-USER> (every 'evenp '(1 2 3 4 5))
NIL

你想做的事情符合这个范式,除了你需要的 f 应该每个 xi,把它当作一个函数,用一些值来调用它。 一些每个仍然在这里工作:

CL-USER> (let ((value 3))
           (some (lambda (predicate) (funcall predicate value)) '(evenp symbolp oddp)))
T
CL-USER> (let ((value "hello"))
           (some (lambda (predicate) (funcall predicate value)) '(characterp numberp)))
NIL

当然,您可以将其包装在另一个函数中,以避免每次都编写 lambda 函数:

(defun some-p (value predicates)
  (some (lambda (predicate)
          (funcall predicate value))
        predicates))

CL-USER> (some-p "hello" '(characterp numberp))
NIL
CL-USER> (some-p 3 '(characterp numberp))
T

如果你真的想让这个函数可变(就像你在你的问题中展示的那样),你可以用一个 &rest 参数来实现,但请注意它不是最流行的风格这些类型的功能使用:

(defun some-p (value &rest predicates)
  (some (lambda (predicate)
          (funcall predicate value))
        predicates))

CL-USER> (some-p 3 'characterp 'numberp)
T
CL-USER> (some-p "hello" 'characterp 'numberp)
NIL

不过,将参数作为列表更为常见。这有两个很好的理由(属于同一现象):(i) 从另一个来源传递列表更容易。例如,[a][b]:

更容易
(let ((preds '(p1 p2 ... pn)))
  (some-p-list value preds)           ; [a]
  (apply 'some-p-rest value preds))   ; [b]

即使您不介意 [b] 中的 apply,因为 ,也有一个常量 call-arguments-limit 在 Common Lisp 实现中,它限制了可以调用函数的参数数量。它通常很大,但也可以小到 50。这意味着如果 preds 有 50 个元素,那么 (apply 'some-p-rest value preds) 会失败。

没有标准函数,但是很容易写:

请注意,您也可以为此使用 LOOP 宏:

一些

CL-USER 10 > (loop with value = 4
                   for pred in (list #'numberp #'plusp #'oddp)
                   thereis (funcall pred value))
T

每个

CL-USER 11 > (loop with value = 3
                   for pred in (list #'numberp #'plusp #'oddp)
                   always (funcall pred value))
T

每个-p

CL-USER 16 > (defun every-p (value predicates)
               (loop for predicate in predicates
                     always (funcall predicate value)))
EVERY-P

CL-USER 17 > (every-p 3 (list #'numberp #'plusp #'oddp))
T