gav*_*koa 2 common-lisp higher-order-functions
总有一些跨值,如列表迭代许多功能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)))
Run Code Online (Sandbox Code Playgroud)
是否有任何标准函数使用语法执行上述代码:
(some-p val pred1 pred2 ... predN)
(every-p val pred1 pred2 ... predN)
Run Code Online (Sandbox Code Playgroud)
更新 FYI Elisp在其标准库中具有此功能:
run-hook-with-args-until-success
run-hook-with-args-until-failure
run-hook-with-args
Run Code Online (Sandbox Code Playgroud)
标准不包括任何与你所要求的完全相同的东西,但它确实包括一些和每一个用于计算(或(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
Run Code Online (Sandbox Code Playgroud)
你想要做的事情适合这个范例,除了你需要的f应该取每个x i,把它当作一个函数,并用一些值来调用它. 一些和每一个仍然在这里工作:
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
Run Code Online (Sandbox Code Playgroud)
当然,你可以在函数中包含另一个函数以避免每次都编写lambda函数:
(defun some-p (value predicates)
(some (lambda (predicate)
(funcall predicate value))
predicates))
Run Code Online (Sandbox Code Playgroud)
CL-USER> (some-p "hello" '(characterp numberp))
NIL
CL-USER> (some-p 3 '(characterp numberp))
T
Run Code Online (Sandbox Code Playgroud)
如果你真的希望函数具有可变参数(就像你在问题中所展示的那样),你可以使用&rest参数来完成它,但要注意这些函数大多使用的风格不是:
(defun some-p (value &rest predicates)
(some (lambda (predicate)
(funcall predicate value))
predicates))
Run Code Online (Sandbox Code Playgroud)
CL-USER> (some-p 3 'characterp 'numberp)
T
CL-USER> (some-p "hello" 'characterp 'numberp)
NIL
Run Code Online (Sandbox Code Playgroud)
但是,将参数作为列表更为常见.两个很好的理由(这是同一现象的一部分)是:(i)从另一个来源传递列表更容易.例如,[a]比[b]更容易做到:
(let ((preds '(p1 p2 ... pn)))
(some-p-list value preds) ; [a]
(apply 'some-p-rest value preds)) ; [b]
Run Code Online (Sandbox Code Playgroud)
即使你不介意适用于[B] ,如赖Joswig注意到 在评论中,有一个恒定的呼叫参数限制在一个Common Lisp实现,它限制对参数的函数可以调用的数量.它通常很大,但它可以小到50.这意味着如果preds有50个元素,那么(应用'some-p-rest值preds)就会失败.