我需要一些帮助,只使用抽象列表函数在方案中进行递归。作为一个例子,我如何使用显式递归更改此代码,以便它不会在正文中具有函数名称:
(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)))]))
谢谢!
答案 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)))))
请注意,在前两个示例中,我使用的是reverse
和foldl
/ fold-left
,而不是foldr
或fold-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-right
和fold-left
或您环境中的等效项。
答案 2 :(得分:1)
可以使用所谓的Y combinator在Scheme中表达匿名的递归函数。我自己没有用过它,但这主要是因为理解它有点棘手。虽然这很有用。