方案中的非显式递归

时间:2013-11-28 05:39:18

标签: recursion scheme

我需要一些帮助,只使用抽象列表函数在方案中进行递归。作为一个例子,我如何使用显式递归更改此代码,以便它不会在正文中具有函数名称:

(define (make_unique_list lst) 
  (cond
    [(empty? lst) empty]
    [(member? (first lst) (rest lst)) (make_unique_list (rest lst))]
    [else (cons (first lst) (make_unique_list (rest lst)))]))

谢谢!

3 个答案:

答案 0 :(得分:3)

在R6RS计划中:

(import (rnrs) (rnrs lists))

(define (make-unique-list lst)
  (reverse
   (fold-left
    (lambda (r e) (if (member e r) r (cons e r)))
    '()
    lst)))

(display (make-unique-list '(1 2 3 4 3 5 6 3 2 1 7)))
=> {1 2 3 4 5 6 7}

在球拍中:

(define (make-unique-list lst)
  (reverse
   (foldl
    (lambda (e r) (if (member e r) r (cons e r)))
    '()
    lst)))

(define (make-unique-list lst)
  (reverse
   (for/fold ((r '())) ((e (in-list lst)))
     (if (member e r) r (cons e r)))))

请注意,在前两个示例中,我使用的是reversefoldl / fold-left,而不是foldrfold-right(请亲自尝试查看原因)。

顺便说一下,这个程序通常被称为remove-duplicates,并且是在Racket内置的:

(remove-duplicates '(1 2 3 4 3 5 6 3 2 1 7))

答案 1 :(得分:1)

看起来可以使用fold。通过将cond中非空案例的逻辑组合成一个累加函数,我们可以选择性地累积列表中尚未看到的项目。

回想一下给折叠的函数有两个参数:一个是当前项,另一个是当前累计值。在这种情况下,当前项目将是X类型,当前累计值将是X的列表。该函数需要返回X列表。

如果您需要保留输入列表的顺序,请明智地选择fold-rightfold-left或您环境中的等效项。

答案 2 :(得分:1)

可以使用所谓的Y combinator在Scheme中表达匿名的递归函数。我自己没有用过它,但这主要是因为理解它有点棘手。虽然这很有用。

另见:https://en.wikipedia.org/wiki/Fixed-point_combinator