Recursion 相互递归函数的不动点组合器?
是否有一个定点组合器来创建相互递归函数的元组?也就是说,我正在寻找类似于Y-Combinator的东西,但它接受多个“递归”*函数,并将返回一组函数Recursion 相互递归函数的不动点组合器?,recursion,functional-programming,mutual-recursion,y-combinator,fixpoint-combinators,Recursion,Functional Programming,Mutual Recursion,Y Combinator,Fixpoint Combinators,是否有一个定点组合器来创建相互递归函数的元组?也就是说,我正在寻找类似于Y-Combinator的东西,但它接受多个“递归”*函数,并将返回一组函数 *:当然不是真正的递归,因为它们以通常的Y-Combinator方式将自己(和兄弟姐妹)作为参数编写。您要寻找的生物是Y*Combinator 基于我将Y*移植到Clojure: (defn Y* [& fs] (map (fn [f] (f)) ((fn [x] (x x)) (fn [p] (ma
*:当然不是真正的递归,因为它们以通常的Y-Combinator方式将自己(和兄弟姐妹)作为参数编写。您要寻找的生物是Y*Combinator 基于我将Y*移植到Clojure:
(defn Y* [& fs]
(map (fn [f] (f))
((fn [x] (x x))
(fn [p]
(map
(fn [f]
(fn []
(apply f
(map
(fn [ff]
(fn [& y] (apply (ff) y)))
(p p)))))
fs)))))
相互递归函数的经典示例为偶数/奇数,因此示例如下:
(let
[[even? odd?]
(Y*
(fn [e o]
(fn [n]
(or (= 0 n) (o (dec n)))))
(fn [e o]
(fn [n]
(and (not= 0 n) (e (dec n)))))
)
]
(do
(assert (even? 14))
(assert (odd? 333))
))
如果使用足够大的参数,可以很容易地使用此函数破坏堆栈,因此这里是它的蹦床版本,例如完全性,它根本不消耗堆栈:
(let
[[even? odd?]
(Y*
(fn [e o]
(fn [n]
(or (= 0 n) #(o (dec n)))))
(fn [e o]
(fn [n]
(and (not= 0 n) #(e (dec n)))))
)
]
(do
(assert (trampoline even? 144444))
(assert (trampoline odd? 333333))
))
Y*combinator对于定义一元语法分析器的相互递归定义非常有用,我将很快在lambder.com上发表博客,敬请关注;)
--
兰德尔我不完全确定这一点。我还在试图找到一个正式的证据。但在我看来你不需要。 在Haskell中,如果您有以下情况: 修正::(a->a)->a
固定f=设x=x中的fx main=让{x=…y…;y=…x…}在x中 您可以将main重写为 main=fst$fix$\(x,y)->(…y…,…x…)
但正如我所说,我不是100%确定这一点。以下网页详细介绍了用于相互递归的固定点组合(多变量固定点组合)。这是迄今为止最简单的一次 组合器。 为了便于参考,这里是Haskell中最简单的多元组合数 (一班轮) 这里是Scheme,一种严格的语言
(define (Y* . l)
((lambda (u) (u u))
(lambda (p)
(map (lambda (li) (lambda x (apply (apply li (p p)) x))) l))))
有关示例和更多讨论,请参见网页。haskell!=λ演算
(define (Y* . l)
((lambda (u) (u u))
(lambda (p)
(map (lambda (li) (lambda x (apply (apply li (p p)) x))) l))))