reverse list

翻转代数类型的链表还挺复杂的

(cons c (cons a (cons t null)))

=>

(cons t (cons a (cons c null)))

这个完全翻转的过程很容易让人联想到利用 lambda 来把参数调用顺序翻过来的过程:

(define (rev&f l f)
  (cond
    ((null? l) (f null))
    (else (rev&f (cdr l) (lambda (new-l)
                           (cons (car l) (f new-l)))))))

(define (rev l) (rev&f l (lambda (l) null)))

想象一下,最后反过来调用的过程应该长这样:

(lambda (new-l3)
    (cons t
        ((lambda (new-l2)
            (cons a 
                ((lambda (new-l1)
                    (cons c
                        (f 
                        new-l1)))
                new-l2)))
        new-l3))) 
null

可以看到 nullnew-l3 传到 new-l2,再到 new-l1,一层层地被传递到最里面

那么有没有办法不通过函数调用,而是直接传到最里面呢?毕竟大伙都知道最里面肯定是个 null

emmm...

(define (rev&f l f)
  (cond
    ((null? l) (f))
    (else (rev&f (cdr l) (lambda ()
                           (cons (car l) (f)))))))

(define (rev l) (rev&f l (lambda () null)))

...silly of me

...

想复杂了好像

(define (rev-helper l new-l)
  (cond
    ((null? l) new-l)
    (else (rev-helper (cdr l) (cons (car l) new-l)))))

(define (rev1 l) (rev-helper l null))