2011-09-14 182 views
6

据我所知,在Clojure中递归而不使用循环.. recur语法对于短序列可能不是问题。但是,使用循环.. recur语法是编写递归函数的首选方法。所以,我想从首选的方法开始。转换为循环...递归递归

然而,我一直在努力这个函数转换[编辑],它返回序列的骨架(序列结构,而没有它的值)

(defn skl 
    [tree] 
    (map skl (filter seq? tree))) 

与此数据测试

(def test_data1 '(1 (2 3) () (()) :a)) 
(def test_data2 '(1 2 (3 4) (5 (6 7 8)))) 

循环..重复语法。任何想法或指针的例子将不胜感激。

回答

3

您可能想要查看允许进行良好结构化树编辑的拉链库,尽管它可能不如您的原始版更优雅。我几乎从不需要使用循环...反复。几乎总是有一个更高阶的函数,以相同或更好的效率更优雅地解决问题。

替换maploop ... recur使代码更加冗长和不太清晰。你也失去了分块序列的好处。

+0

谢谢。你指的是Clojure.zip,对吧?我知道它,会使用它,并希望没有这个练习。 – octopusgrabbus

+0

除了loop-recur,蹦床也是一个有趣的功能,尽管在这里并不直接适用。 –

4

循环和重复是一个简单迭代的转换。然而,下降到树中本质上是递归的。您将不得不手动维护堆栈以将其转换为单个迭代。因此,您的代码没有“简单”转换。

+0

谢谢。我知道Clojure.zip,但想通过滚动我自己来尝试提取骨架。这个例子来自UPenn的一些研究生计算机科学练习。你的回答至少告诉我这不是一个简单的问题要解决。谢谢。 – octopusgrabbus

1

看看clojure.walk源代码。它是一个对所有Clojure嵌套数据结构(不包括有序地图)进行(批量)操作的库。这里有一些非常强大但看似简单的代码,通过本地定义的匿名函数使用递归而不使用循环/循环。

那里的大多数功能都是基于步行道和prewalk功能,而这些功能又都是基于漫游功能。通过源代码和(prewalk-demo表单)和(postwalk-demo表单),您可以深入了解所采取的递归步骤。

我不知道这是否可以帮助你解决你的问题。我正在尝试在同一个问题域中做一些事情:创建一个函数,将嵌套的映射和向量“扁平化”为从根到叶的所有路径的序列,每个路径的一系列键和/或索引以'叶'价值。

这个库似乎在整个结构中递归编辑值非常简单。然而,我仍然不知道如何使用它来在功能上跟踪我的'路径'所需的迭代之间的累积数据,并且可能还有'骨架'问题。