3

我正在为遗传编程问题创建 s 表达式树,并且需要在进化过程中更改部分树。我遇到了Clojure 拉链功能,它看起来应该是完美的,但对于我的生活,我无法弄清楚如何使用它。

例如,假设我创建了一个拉链

(def zipped (zip/seq-zip `(+ (- 1 2) 3)))

我理解这表示以 + 为根的树,它看起来像这样:

   +
 -   3
1 2

但是,我的拉链不同意这一点:如果我要求第一个节点,(-> zipped zip/down zip/node)它会给我+(这是正确的),但它(-> zipped zip/down zip/down)不会带我去-,而是返回nil. 确实,(-> zipped zip/down zip/rights)将树的其余部分作为根右侧的兄弟姐妹,这表明我根本没有树:

user> (-> zipped zip/down zip/rights)
((clojure.core/- 1 2) 3)

我很确定我正确地表示了我的树,因为当我执行它们时,我得到了正确的答案。拉链是否期望不同的布局?

4

2 回答 2

3

问题是这里有两种不同的树概念。您的树是值如何通过评估渗透的图表,但 LISP 正在考虑列表列表,并使用前缀表示法:

'(+ (- 1 2) 3) 也是 (list + (list - 1 2) 3),其实就是这棵树:

+  .     3
   - 1 2

(-> zipped down node)给你第一个元素+,一个原子。 (-> zipped down down)因此给你 nil 因为第一个元素 + 是一个原子。 (-> zipped down right down node)给你你想要的减号,因为这是表达式的第二个元素的第一个元素。

于 2010-10-11T00:51:38.300 回答
1

这棵树不是您绘制的图表。根节点有 3 个子节点:+(- 1 2)3。当您down从根节点执行时,它默认为最左边的子节点,因此您会看到+.

要到达-您需要致电:

用户=> (-> zipped zip/down zip/right zip/down zip/node)
clojure.core/-
于 2010-10-11T00:51:07.593 回答