【问题标题】:How do you call functions in a list of functions in Lisp?如何在 Lisp 中调用函数列表中的函数?
【发布时间】:2013-04-30 19:13:40
【问题描述】:

我正在阅读 Practical Common Lisp,并且正在研究 REPL 中的闭包(第 6 章)。我正在尝试以下代码,我认为它列出了闭包,但我不知道如何在 REPL 中同时调用它们:

(defparameter *fn*
   (let ((count 10))
     (list
      #'(lambda () (incf count))
      #'(lambda () (decf count))
      #'(lambda () count))))

我已阅读this question 的答案并尝试了一些和其他一些,但似乎没有任何效果。这是我尝试过的--

CL-USER> (apply #'funcall *fn*)
; Evaluation aborted on #<CCL::TOO-MANY-ARGUMENTS #x2100B8890D>.
CL-USER> (funcall *fn*)
; Evaluation aborted on #<TYPE-ERROR #x2100B5667D>.
CL-USER> (loop for function in *fn*
      (collect (funcall function)))
; Evaluation aborted on #<CCL::SIMPLE-PROGRAM-ERROR #x2100C21D4D>.
CL-USER> (map #'funcall *fn*)
; Evaluation aborted on #<CCL::TOO-FEW-ARGUMENTS #x2100B7320D>.

我正在寻找的是可以打印的东西 (11 9 10)。

感谢您的帮助!

【问题讨论】:

    标签: lisp closures common-lisp


    【解决方案1】:

    您可以使用mapcar 代替map

    CL-USER> (mapcar #'funcall *fn*)
    (11 10 10)
    

    但是,您会注意到打印的是 (11 10 10) 而不是 (11 9 10)。这是因为count*fn* 中的lambda 之间共享,因为let 范围将它们全部包含在内。

    如果您希望 count 绑定到每个 lambda 中的不同变量,则必须为每个 lambda 构建不同的 let 范围。

    【讨论】:

    • 谢谢,这很有帮助!
    【解决方案2】:
    (funcall (first *fn*))
    
    (loop for f in *fn* collect (funcall f))
    
    (map 'list #'funcall *fn*)
    
    (mapcar #'funcall *fn*)
    

    【讨论】:

      猜你喜欢
      • 2014-11-28
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-15
      相关资源
      最近更新 更多