作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
编辑 : 我在写这篇文章的过程中发现了我自己问题的部分答案,但我认为它可以很容易地改进,所以我还是会发布它。也许那里有更好的解决方案?
我正在寻找一种在 let
中定义递归函数的简单方法。形式不诉诸letfn
.这可能是一个不合理的要求,但我正在寻找这种技术的原因是因为我混合了数据和递归函数,这些函数在某种程度上相互依赖,需要大量嵌套 let
和 letfn
陈述。
我想编写生成这样的惰性序列的递归函数(以斐波那契序列为例):
(let [fibs (lazy-cat [0 1] (map + fibs (rest fibs)))]
(take 10 fibs))
fibs
在绑定(bind)期间不能使用它自己的符号。明显的解决方法是使用
letfn
(letfn [(fibo [] (lazy-cat [0 1] (map + (fibo) (rest (fibo)))))]
(take 10 (fibo)))
let
和
letfn
.
letfn
的情况下执行此操作并且只使用
let
,我开始写一些使用我认为是 U-combinator 的东西(今天才听说这个概念):
(let [fibs (fn [fi] (lazy-cat [0 1] (map + (fi fi) (rest (fi fi)))))]
(take 10 (fibs fibs)))
(fi fi)
的冗余?
(let [Q (fn [r] ((fn [f] (f f)) (fn [y] (r (fn [] (y y))))))
fibs (Q (fn [fi] (lazy-cat [0 1] (map + (fi) (rest (fi))))))]
(take 10 fibs))
Q
称为我用来定义递归序列的组合器?它看起来像没有参数的 Y 组合器
x
.是一样的吗?
(defn Y [r]
((fn [f] (f f))
(fn [y] (r (fn [x] ((y y) x))))))
最佳答案
莱特雷克
我写了一个letrec
Clojure 最近的宏,这里是 a Gist of it .它的作用类似于 Scheme 的 letrec
(如果你碰巧知道的话),这意味着它是 let
之间的交叉。和 letfn
:您可以将一组名称绑定(bind)到相互递归的值,而无需将这些值作为函数(惰性序列也可以),只要可以在不引用其他项目的情况下评估每个项目的头部(那就是Haskell - 或者可能是类型理论 - 用语;这里的“头”可能代表惰性序列对象本身,具有 - 至关重要! - 不涉及强制)。
你可以用它来写东西,比如
(letrec [fibs (lazy-cat [0 1] (map + fibs (rest fibs)))]
fibs)
(letfn [(fibs [] (lazy-cat [0 1] (map + (fibs) (rest (fibs)))))]
(fibs))
letrec
版本具有线性复杂度(顶级
(def fibs (lazy-cat [0 1] (map + fibs (rest fibs))))
形式也是如此)。
iterate
构建。 - 即当固定范围的后视足以计算任何给定元素时。见
clojure.contrib.lazy-seqs
有关如何计算
fibs
的示例与
iterate
.
c.c.seq
提供了一个有趣的函数,叫做
rec-seq
,启用诸如
(take 10 (cseq/rec-seq fibs (map + fibs (rest fibs))))
clojure.contrib.with-ns
了解实现思路)。
letrec
这与惯用的 Clojure 相去甚远,如果还有其他方法可以做的话,我会避免在生产代码中使用它(而且因为总是有顶级选项......)。然而,它(IMO!)很好玩,而且它似乎工作得很好。我个人很想知道在没有
letrec
的情况下可以完成多少工作。以及到什么程度
letrec
宏使事情变得更容易/更清洁......我还没有对此形成意见。所以,就在这里。再一次,对于单个自递归 seq 案例,
iterate
或 contrib 可能是最好的方法。
关于binding - 如何在 Clojure 中创建一个生成惰性序列的匿名递归函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3373157/
我是一名优秀的程序员,十分优秀!