是否有任何标准函数可以通过应用于单个值来遍历谓词?
Are there any standard functions to iterate across predicates by applying to single value?
总是有很多函数可以遍历值列表,例如 mapcar
、every
、some
。
我需要对单个值进行谓词迭代:
(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
该标准不包括与您要求的完全相同的任何内容,但它确实包括 some 和 every 用于计算(或(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
总是有很多函数可以遍历值列表,例如 mapcar
、every
、some
。
我需要对单个值进行谓词迭代:
(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
该标准不包括与您要求的完全相同的任何内容,但它确实包括 some 和 every 用于计算(或(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,因为
没有标准函数,但是很容易写:
请注意,您也可以为此使用 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