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)))
是否有任何标准函数使用语法执行上述代码:
(some-p val pred1 pred2 ... predN)
(every-p val pred1 pred2 ... predN)
更新 FYI Elisp在其标准库中具有此功能:
run-hook-with-args-until-success
run-hook-with-args-until-failure
run-hook-with-args
标准不包括任何与你所要求的完全相同的东西,但它确实包括一些和每一个用于计算(或(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应该取每个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
当然,你可以在函数中包含另一个函数以避免每次都编写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] ,如赖Joswig注意到 在评论中,有一个恒定的呼叫参数限制在一个Common Lisp实现,它限制对参数的函数可以调用的数量.它通常很大,但它可以小到50.这意味着如果preds有50个元素,那么(应用'some-p-rest值preds)就会失败.
| 归档时间: | 
 | 
| 查看次数: | 79 次 | 
| 最近记录: |