3
votes

I'm trying to sum all integers in a list of structs using a recursive function but cannot for the life of me figure it out.

(struct number (int))
(define ints (list (number 1)
                   (number 2)
                   (number 3)))

(define sum (λ (number)
            (cond
              ((null? number) 0) ; Base Case
              (#t (+ (number-int (car ints)) ; Take the first of the list
                     (sum (cdr ints))))))) ; Rest the list

I've spent hours trying different variations of:

(cdr ints), i.e. (number-int (cdr ints)) for the last line

As I believe it's this which is causing the issue (both (cdr ints) and (number-int (cdr ints)) return something in the form of '(#<number> #<number>). But nothing seems to work!

Is there a procedure to returning the cdr of the list in the form of a list of integers rather than '(#<number> #<number>)?

Any help will be greatly appreciated.

2
"ints" is very badly named; suggests it's a list of ints but it's a list of "numbers" (i.e. structs); so better name could be numbers. then, define either sum-numbers function, to be called as (sum-numbers numbers), or sum-ints, to be called as (sum-ints (map number-int numbers)). the first expects numbers, i.e. a list of number structs; the second expects a list of ints, so we must transform the list of "number" structs into a list of int numbers, for it (using map).Will Ness

2 Answers

0
votes

Try this:

(define sum 
  (λ (lst)
    (cond ((null? lst) 0)
          (else (+ (number-int (car lst))
                   (sum (cdr lst)))))))

Some remarks:

  • Use else instead of #t for the last condition in a cond expression
  • You were mixing the name of the procedure's parameter number with the name of the ints list you defined outside
  • Better rename it to lst or something else that makes it clear that is a list you're dealing with

Now it works as expected:

(sum ints)
=> 6
0
votes

A recursive named let with a variable to store sum values can be used:

(define (sum lst)
  (let loop ((lst lst)
             (s 0))
    (if (empty? lst)
        s
        (loop (cdr lst)
              (+ s
                 (number-int (car lst)))))))