2017-01-20 92 views
0

我是球拍和一般功能語言的新手。現在我只是試圖將項目添加到列表中。這些概念有點混亂,不知道爲什麼我的代碼無法正常工作。將元素添加到球拍中新定義的列表中

我正在嘗試做點積計算。

我有一個名爲「dProduct」的函數,它需要2個列表(A和B)並將它們中的每個對應元素相乘。

;function takes dot product 
    (define (dProduct A B) 

     (define C '()) ; define list to store the multiplied elements 

     ;multiply ea lists elements 
     (for ([i A] [j B]) 
     (display (* i j)) ;THIS WORKS 
     (cons (* i j) C) ;APPARENTLY DOESN'T WORK 
    ) 

     ;THIS FOR LOOP DISPLAYS NOTHING 
     ;display the new list "C" 
     (for ([k C]) 
     (display k) 
    ) 

    ) 

我不明白爲什麼我不能用cons來將新的乘法元素預先添加到我的新列表「C」中。我錯過了什麼?一切都很好。想弄清楚這個,所以我可以完成這個功能:)任何幫助將是偉大的。謝謝!

+0

免費計劃書:[如何設計程序](http://www.htdp.org)(也鏈接到DrRacket的內置幫助,本身很棒); [計算機程序的結構和解釋](https://mitpress.mit.edu/sicp/full-text/book/book.html)。 – molbdnilo

回答

3

列表是不可變的,並且cons確實是而不是將元素預先加入到現有列表中。相反,它會產生一個新的列表除了前面元素:

> (define x '(2 3)) 
> (cons 1 x) 
'(1 2 3) 
> x 
'(2 3) 

由於您的問題被標記,我會認爲你可能想知道如何在功能上做到這一點,和函數式編程一般不鼓勵變異值或綁定。

而不是變異的綁定,你應該在功能上建立一個新的結構。要做到這一點最簡單的方法是你的for使用更改爲for/list,其產生的返回值的列表:

(define C 
    (for/list ([i A] [j B]) 
    (* i j))) 

對於這個程序,你可以使它更簡單的使用高階函數map,這就像當設置多於一個list參數一個「拉鍊」:

(define C (map * A B)) 

由於for總是返回#<void>,它只是用於生產的副作用是有用的,在函數式編程,你通常儘量保持副作用降到最低。因此,您可能會發現for/listfor/fold實際上在慣用球拍中比普通for更常用。

-1

當前C名單已經被賦予的(cons (* i j) C)新值,這可以使用set!做到:

(define (dProduct A B) 

    (define C '()) 

    (for ([i A] [j B]) 
    (displayln (* i j))   
    (set! C (cons (* i j) C))) ; NOTE set! HERE. 

    (for ([k C]) 
    (displayln k))) 

注意的是,使用set!是非常令人氣餒的for/list是更好的方法,在這裏實現期望的結果。