Recursion 相互递归函数的不动点组合器?

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*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))))