有人可以幫助我準確地分解下列版本拼合的執行順序嗎?我正在使用Racket。球拍/計劃拼合說明
版本1,是來自球拍本身,而版本2更常見?實現。現在
(define (flatten1 list)
(let loop ([l list] [acc null])
(printf "l = ~a acc = ~a\n" l acc)
(cond [(null? l) acc]
[(pair? l) (loop (car l) (loop (cdr l) acc))]
[else (cons l acc)])))
(define (flatten2 l)
(printf "l = ~a\n" l)
(cond [(null? l) null]
[(atom? l) (list l)]
[else (append (flatten2 (car l)) (flatten2 (cdr l)))]))
,運行與第一實施例「(1 2 3)生產:
l = (1 2 3) acc =()
l = (2 3) acc =()
l = (3) acc =()
l =() acc =()
l = 3 acc =()
l = 2 acc = (3)
l = 1 acc = (2 3)
'(1 2 3)
而第二生產:
l = (1 2 3)
l = 1
l = (2 3)
l = 2
l = (3)
l = 3
l =()
'(1 2 3)
執行的順序似乎不同。在第一個示例中,它看起來像第二個循環(loop (cdr l) acc)
在'(2 3)'正在立即打印之後在第一個循環之前觸發。而在第二個例子中,在'(2 3)之前打印1,這看起來是第一個要在append內部變平的調用,首先進行評估。
我正在通過Little Schemer,但這些都是比較困難的例子,我真的可以使用一些幫助。
非常感謝。
謝謝。但是在例2中,爲什麼(循環(cdr l))會在(循環(car l))之前被觸發,而(flatten2(car l))會在之前觸發(flatten2(cdr l))? – Scott
因此,在'flatten1'中,'cdr'在'car'前面,因爲我描述的原因:累加器列表是從右到左構建的。在'flatten2'中,順序無關緊要,但是球拍在評估表達式時總是使用從左到右的順序,所以這就是爲什麼你在'cdr'之前看到'car'的原因。 –
好的,謝謝。所以在Racket中,列表(cons)是從右到左建立的,但表達式從左到右進行評估。這有幫助。 – Scott