2

以下是令人惊叹的书籍“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函数分成多行吗?

4

1 回答 1

1

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

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

您必须像这样阅读代码:

  • 每个边对都是一个 cons 列表。每个 cons 存储一个位置。
  • 循环返回边对列表。
  • 然后将 append 应用于此列表并返回 conses 列表。conses 列表实际上是一个位置列表。

请注意,该函数有几个小问题:

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

  • 更重要的是,如果我们稍微改变一下 LOOP,就不需要应用 APPEND 函数。LOOP 不仅可以 COLLECT,还可以 APPEND。

于 2010-11-18T08:18:58.763 回答