是否可以使用call / cc来实现递归?

时间:2012-03-29 08:42:24

标签: functional-programming scheme callcc

我想知道是否有可能定义一个递归函数而不在其体内调用函数本身,但不知何故使用call / cc代替?感谢。

3 个答案:

答案 0 :(得分:13)

您可以使用call/ccas described here来实现Y组合器。 (非常感谢John Cowan提到这个简洁的帖子!)引用那篇文章,这是Oleg的实现:

  

推论1. Y组合子通过call/cc - Y组合子没有明确的自我应用。

(define (Y f)
  ((lambda (u) (u (lambda (x) (lambda (n) ((f (u x)) n)))))
   (call/cc (call/cc (lambda (x) x)))))
     

在这里,我们使用了一个事实

((lambda (u) (u p)) (call/cc call/cc))
     

((lambda (u) (u p)) (lambda (x) (x x)))
     

在观察上是等价的。

答案 1 :(得分:6)

你的问题有点模糊。特别是,听起来你想要一个使用call / cc来模拟递归调用而不直接进行递归调用的系统。但事实证明,您可以在不进行递归调用的情况下对递归调用进行建模,而在不使用call / cc的情况下也可以 。例如:

#lang racket

(define (factorial f n)
  (if (= n 0) 1 (* n (f f (- n 1)))))

(factorial factorial 3)

这可能看起来像作弊,但它是Y组合者的基础。也许你可以收紧你想到的一系列限制?

P.S。:如果这是作业,请引用我!

答案 2 :(得分:2)

我担心call/cc与此无关。实际上只有两种定义递归函数的方法:

  • 假设您的语言允许递归函数定义;即,函数体可以引用封闭函数,或者函数f的体可以引用其身体引用g的函数f。在这种情况下,你只需按照通常的方式编写它。
  • 如果您的语言禁止这两种语言,但它仍然具有一流的功能和lambda,那么您可以像Y组合子一样使用fixed-point combinator。你编写你的函数,以便它作为一个额外的参数,一个函数,用于表示递归步骤;你要递归的每个地方,而不是你调用那个论点。

因此,对于factorial,您可以这样写:

(define (factorial-step recurse n)
  (if (zero? n)
      1
      (* n (recurse (- n 1)))))

Y组合子的神奇之处在于它构造了recurse函数,该函数将被馈送到factorial-step