问题
(define-struct position (name numshares share-price))
(define p1
(cons (make-position "INT" 10 192) (cons (make-position "SSS" 4 42)
empty)))
mult
is my helper function
(define (mult n)
( * (position-numshares n)
(position-share-price n)))
const takes the position-numshares and the position-share-price in a list and multiplies them together.
(define (const n)
(cond
[(empty? n) empty]
[(cons? n)
(+ (mult (first n))
)]))
What I would like to do is take the first of the list and add the rest of the list together. Instead, I only get the first of the list. So if I do (const p1) I only get 1920, but I would like to get 2088 (10*192 + 4*42). I've tried recurring for the rest, but get an error. I am probably missing something simple. Help would be appreciated.
回答1:
First, note that in general, you can do
(list a b)
instead of
(cons a (cons b empty))
so you define p1
with
(define p1
(list (make-position "INT" 10 192)
(make-position "SSS" 4 42)))
which is easier to read, and makes your intent clearer. Now, to get 1920
from a structure created by (make-position "INT" 10 192)
, you've defined your helper procedure mult
. You can map
mult
over your list p1
to get a new list of the products, i.e., (1920 168)
. Then you can use foldl with +
and 0
on that list to compute its sum.
(define (const lst)
(foldl + 0 (map mult lst)))
(const p1)
;=> 2088
If you don't want to use fold
and map
(which might be reasonable, since map
means that a new list is getting allocated), you can write this out manually:
(define (const lst)
(let const ((sum 0) (lst lst)) ; pretty much an implementation of fold, but
(if (null? lst) ; with the function + built in, and mult applied
sum ; to each element before passing to +
(const (+ sum (mult (car lst)))
(cdr lst)))))
(const p1)
;=> 2088
Another alternative would be to use foldl
, but instead of passing +
, pass in a function that combines +
and mult
:
(define (const3 lst)
(foldl (lambda (struct sum)
(+ (mult struct) sum))
0
lst))
(const3 p1)
As a Common Lisper, it's a bit disappointing to me that Scheme's foldl
procedure doesn't take a key argument that gets applied to each element of the list before the function is applied to it. In Common Lisp, we'd write (foldl
/foldr
are reduce in Common Lisp):
(reduce '+ p1 :key 'mult)
来源:https://stackoverflow.com/questions/19338153/scheme-structures-and-lists