2017-01-20 43 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是更好的方法,在这里实现期望的结果。