我想將原子添加到列表的末尾,並且還希望原始列表發生更改。我已經寫了這個小程序,但它不會改變列表。爲什麼是這樣的,我該如何改變它。 PS:我是新來的計劃。將原子添加到方案中的列表中
(define (append! l1 l2)
(set! l1 (append l1 (list l2)))
)
我想將原子添加到列表的末尾,並且還希望原始列表發生更改。我已經寫了這個小程序,但它不會改變列表。爲什麼是這樣的,我該如何改變它。 PS:我是新來的計劃。將原子添加到方案中的列表中
(define (append! l1 l2)
(set! l1 (append l1 (list l2)))
)
只需使用句法擴展:
(define-syntax-rule (append! l1 at)
(set! l1 (append l1 (list at))))
然後
> (define l1 '(1 2 3))
> (append! l1 4)
> l1
'(1 2 3 4)
與您的實現問題是,你只是改變一個函數的參數,但功能退出後功能列表「外部」保持不變。我們可以修改就地使用set-car!
和set-cdr!
列表中,但它是一個有點棘手,因爲首先我們要找到合適的cons
細胞進行修改,並返回列表的頭:
(define (append! lst atom)
(let ((head lst))
(let loop ((lst lst))
(cond ((null? lst) (list atom))
((null? (cdr lst))
(set-cdr! lst (list atom))
head)
(else (loop (cdr lst)))))))
(define l1 '(1 2 3 4))
l1
=> '(1 2 3 4)
(append! l1 5)
l1
=> '(1 2 3 4 5)
甚至更好,我們可以忘掉到位變異名單和接受功能的編程風格,這是推薦的方式使用計劃時:
(define l1 '(1 2 3 4))
(define (append-tail lst atom)
(append lst (list atom)))
(define l2 (append-tail l1 5))
l1
=> '(1 2 3 4)
l2
=> '(1 2 3 4 5)
有set!
是變異的結合,但沒有價值,有set-car!
和set-cdr!
變異值,如果是一對。
set!
作爲改變任務。因此,如果您有x
和y
都是值"value"
並使用set!
將x
更改爲"anothervalue"
。如果您有一個過程併爲其中一個參數指定了不同的值,您將重新定義本地名稱,而不會更改傳遞給該過程的變量。
set-car!
和set-cdr
成對工作。因此,它們會改變數值並與變量無關。
如:
(define x (list 1 2 3)) ; x is (1 2 3)
(define y x) ; y is (1 2 3)
(define z y) ; z is (1 2 3)
;; changing the binding of z
(set! z (append x '(1))) ; z is (1 2 3 1) while x and y still are (1 2 3)
;; changing the value of x
(set-car! x 2) ; both x and y are now (2 2 3)
考慮到這一點,你可以改變一個變量,但請記住,這非常變量可以有與其他變量共享結構,因此你可能會比你最初雖然使用set-cdr!
改變更多變數
#!r6rs
(import (rnrs)
(rnrs mutable-pairs))
(define (append-elt! lst value)
(when (null? lst)
(assertion-violation 'append! "lst cannot be null" lst))
(let loop ((lst lst))
(if (null? (cdr lst))
(set-cdr! lst (list value))
(loop (cdr lst)))))
(define q (append y y)) ; We make a copy of y with y as shared tail
(append-elt! q 'a) ; we change the last pair of q which also is the last pair of y and z
q ; ==> (1 2 3 1 2 3 a)
x ; ==> (1 2 3 a)
z ; ==> (1 2 3 a)
那麼問題是,我想在另一個使用這個功能,所以這並沒有多大幫助。 – pesho 2014-12-04 21:04:18
@pesho我更新了我的答案,其中更接近於你想要的東西,但請相信我:在Scheme中,這不是正確的做事方式,建議不要改變列表的版本 - 正如你所說,你只是在學習Scheme,所以如果你開始以正確的方式做事,會更好。 – 2014-12-04 21:23:57