Recursion 迭代映射格式

Recursion 迭代映射格式,recursion,scheme,lisp,iteration,sicp,Recursion,Scheme,Lisp,Iteration,Sicp,我正在观看SICP视频讲座,我来到了一个部分,导师们正在展示处理列表的程序,下面是其中之一: (define (map p l) (if (null? l) (list) (cons (p (car l)) (map p (cdr l))))) 我想问的是:有没有一种方法可以用迭代的方式定义map,或者cons需要执行惰性计算,对吗?为了总体上理解SICP和Scheme,你需要拥抱递归,所以试着习惯它,你以后会理解的,

我正在观看SICP视频讲座,我来到了一个部分,导师们正在展示处理列表的程序,下面是其中之一:

(define (map p l)
   (if (null? l) 
       (list)
       (cons (p (car l))
                    (map p (cdr l)))))

我想问的是:有没有一种方法可以用迭代的方式定义
map
,或者
cons
需要执行惰性计算,对吗?

为了总体上理解SICP和Scheme,你需要拥抱递归,所以试着习惯它,你以后会理解的,我保证

但是,你可以:

(define (iterative-map f lst)
  (define res null)
  (do ((i (- (length lst) 1) (- i 1))) ((= i -1))
    (set! res (cons (f (list-ref lst i)) res)))
  res)

(iterative-map (lambda (x) (+ x 1)) '(1 3 5))
=> '(2 4 6)
但是使用
set被视为不良样式

在球拍中,您有一套不同的更优雅的环:

(define (for-map f lst)
  (for/list ((i lst))
    (f i)))

(for-map add1 '(1 3 5))
=> '(2 4 6)

您的原始代码几乎是尾部递归的。。唯一能让它变得不一样的是
cons
部分。如果Scheme对have-as-have需求有相同的需求,那么您可以保持代码的原样,并且实现会使它对您来说是尾部递归的

因为这不是一个要求,我们需要做我们自己的TRMC优化。通常,当在循环中迭代列表并使用累加器使其尾部递归时,您会以相反的顺序得到结果,因此您可以执行反向线性更新:

(define (map proc lst)
  (let loop ((lst lst) (acc '()))
    (cond ((null? lst) (reverse! acc) acc)
          (else (loop (cdr lst) 
                      (cons (proc (car lst)) acc))))))
或者您可以一次完成所有操作:

(define (map proc lst)
  (define head (list 1))
  (let loop ((tail head) (lst lst))
    (cond ((null? lst) (cdr head))
          (else (set-cdr! tail (list (proc (car lst))))
                (loop (cdr tail) (cdr lst))))))
现在,在这两种情况下,您只需修改过程本身创建的结构,因此对于用户来说,它的实现方式可能与您的示例相同


当您从实现中使用更高阶的过程(如
map
)时,可能会发生这样的情况。通过比较所提供的
map
上的性能和具有很长列表的不同实现,很容易找到答案。执行之间的差异将告诉您是否是TRMCO,或者所提供的
map
可能是如何实现的。

您的意思是什么?
cons
@molbdnilo中没有懒惰,他希望它要么像Haskell一样懒惰,要么像Haskell一样懒惰。谢谢。不要认为我在递归方面有问题(我实际上很喜欢它),我只是想知道如何用另一种方式实现它。若你们想接受这个方案,你们需要避免变异。(哎呀!)@leppie没有办法让
映射
尾部递归而没有变异,所以每个答案都会有。@Sylwester:你唯一使用的变异是
反向
(在这种情况下是安全的),所以我不明白你的意思。@leppie这里坏的不是突变,而是用来反向迭代列表的
list ref
。我的观点是,你需要一个高效的
map
来补偿单链表的性质。我的第二个版本使用
set-cdr和它的两倍快的第一和10倍OP的原始例子。“任何提到TRMC会得到一个自动向上投票从我:)想想看,从那时起(在方案背景下)它就一直被忽视!!