我学过编程语言课程,我在幻灯片中有这个Scheme代码的变体:
; (listof any) -> (listof any[no-cons])
(define (remove-pairs l)
(cond
[(empty? l) '()]
[else
(let ([ans
(if (cons? (first l))
(begin (free! (first l))
(remove-pairs (rest l)))
(cons (first l)
(remove-pairs (rest l))))])
(free! l) ; <- this will break our tail recursion.
ans)]))
在代码中,(free! l)
会破坏我们的尾递归。我不知道这个功能是做什么的,我没有任何意义。
答案 0 :(得分:0)
如果没有看到free!
的代码,就不可能知道这个函数应该做什么。可以推断的是,过程删除列表中不是cons
单元格的每个元素,构建并返回一个只包含非{{1}元素的新列表从一开始就是细胞。
声明函数是尾递归是不正确的 - 它永远不会开始,无论cons
做什么,递归调用都不在尾部位置。
这是使用尾递归实现推断功能的正确的方法,请注意问题中递归的结构完全错误,而不是尾递归:
free!
从更实际的角度来看,你可以使用(define (remove-pairs l)
(let loop ((lst (reverse l))
(acc '()))
(cond [(empty? lst)
acc]
[(cons? (first lst))
(free! (first lst)) ; whatever that is
(loop (rest lst) acc)]
[else
(loop (rest lst) (cons (first lst) acc))])))
获得相同的功能,虽然这不能保证是尾递归的:
filter
无论哪种方式,这都是它的工作原理:
(define (remove-pairs l)
(filter (lambda (x)
(cond [(cons? x)
(free! x) ; whatever that is
#f]
[else #t]))
l))