时间:2010-11-18 01:36:48

标签: functional-programming lisp land-of-lisp

以下是一本惊人的书“Land of Lisp”中的一个例子的源代码:

(defun random-node ()
  (1+ (random *node-num*)))

(defun edge-pair (a b)
  (unless (eql a b)
     (list (cons a b) (cons b a))))

(defun make-edge-list ()
    (apply #'append (loop repeat *edge-num*
                          collect (edge-pair (random-node) (random-node)))))

由于我没有 Lisp本能,我发现将方法分解为多行(作为命令式样式)然后尝试将其转换为功能样式是有用的。

请你帮我把make-edge-list功能分成多行?

1 个答案:

答案 0 :(得分:1)

Lisp中的行无意义。 Lisp表示法基于s表达式,并且在评估期间Lisp不会看到文本行。你可以在空格上以任何方式分解表达式。

(defun make-edge-list ()
   (apply #'append
          (loop repeat *edge-num*
                collect (edge-pair (random-node)
                                    (random-node)))))

您必须阅读以下代码:

  • 每个边对都是一个圆锥列表。每个利弊都有一个职位。
  • 循环返回边对的列表。
  • 然后将append应用于此列表并返回一个conses列表。 conses列表实际上是一个职位列表。

请注意,该功能有几个小问题:

  • APPLY不适用于任意长度的列表。所以我们希望列表不会太长。

  • 更重要的是,如果我们稍微更改LOOP,则不需要应用APPEND功能。 LOOP不仅可以收集,还可以APPEND。