0

I'm trying to create a scheme program that adds the elements of a given list (both simple and nested).


(define (adder a_list)
  (cond
    ((null? a_list) 0)
    ((list? (car a_list))(adder (car a_list)))
    (else (+ (car a_list) (adder (cdr a_list))))
    )
  )

(adder '(2 (5 4) 6))```

The problem I'm running into is that when I run this, it only adds (5+4) + 2, and then doesn't add the 6. So my output is 11 rather than 17. I know my null statement at the top is causing this issue, but when I take it out I get this error:

  car: contract violation
  expected: pair?
  given: '()

Any tips would be greatly appreciated.

1
  • 1
    So, translated: the sum of the empty list is 0; the sum of a list whose first element is a list is the sum of only its first element; and for everything else, add the first element to the sum of the tail. (The null case is actually correct; your problem is the second case.) Commented Sep 14, 2022 at 5:36

1 Answer 1

0
(define (adder a*)
  (if (null? a*)
      0
      (+ (if (pair? (car a*))
             (adder (car a*))
             (car a*))
         (adder (cdr a*)))))

And, shorter:

(define ++
  (lambda (a*)
    (fold-left (lambda (a x)
                 (+ a (if (pair? x) (++ x) x)))
               0
               a*)))

(written in mit/scheme)

Sign up to request clarification or add additional context in comments.

2 Comments

I think fold-left is more powerful than you really need here. Just do a map phase first, to turn any nested lists into their sum, and then (apply +) the resulting list. (define (++ x) (if (pair? x) (apply + (map ++ x)) x))
@amalloy While syntactically it is simpler, I think semantically it is more complex, as map acummulates lists that are passed to apply, while the folds do not pass the full lists but use only an accummulator register that is returned at the end.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.