Question

i have a function in scheme, this function calls another function many times, and every time this function appends return value of another function to result value. but finally i want to get a result such that '(a b c), however i get a result such that '((a) (b) (c)) how can i fix this problem? i have searched but i couldn't find good solution.

my little code like that not all of them.

(append  res  (func x))
(append  res  (func y))
(append  res  (func z))

my code like this

(define (check a )  
'(1)
)

(define bos '())
(define (func a)
(let loop1([a a] [res '()]) 
(cond 
[(eq? a '()) res] 
[else (let ([ x (check (car a))]) 
(loop1 (cdr a) (append  res (list x)))
)]
)
))
Was it helpful?

Solution

Try this:

(define (func a)
  (let loop1 ([a a] [res '()])
    (cond 
      [(eq? a '()) res]
      [else
       (let ([ x (check (car a))]) 
         (loop1 (cdr a) (append res x)))])))

Notice that the only change I made (besides improving the formatting) was substituting (list x) with x. That will do the trick! Alternatively, but less portable - you can use append* instead of append:

(append* res (list x))

As a side comment, you should use (null? a) for testing if the list is empty. Now if we test the procedure using the sample code in the question, we'll get:

(func '(a b c))
=> '(1 1 1)

OTHER TIPS

It seems that instead of

(loop1 (cdr a) (cdr b) c (append  res (list x)))

you want

(loop1 (cdr a) (cdr b) c (append  res x))

Basically the trick is to use cons instead of list. Imagine (list 1 2 3 4) which is the same as (cons 1 (cons 2 (cons 3 (cons 4 '())))). Do you see how each part is (cons this-iteration-element (recurse-further)) like this:

(define (make-list n)
  (if (zero? n)
      '()
      (cons n (make-list (sub1 n)))))

(make-list 10) ; ==> (10 9 8 7 6 5 4 3 2 1)

Usually when you can choose direction you can always make it tail recursive with an accumulator:

(define (make-list n)
  (let loop ((x 1) (acc '()))
    (if (> x n)
        acc
        (loop (add1 x) (cons x acc))))) ; build up in reverse!


(make-list 10) ; ==> (10 9 8 7 6 5 4 3 2 1)

Now this is a generic answer. Applied to your working code:

(define (func a)
  (let loop1 ([a a] [res '()]) 
    (cond 
      [(eq? a '()) (reverse res)] 
      [else 
       (let ([x (check (car a))]) 
         (loop1 (cdr a) (cons (car x) res)))])))

(func '(a b c)) ; ==> (1 1 1)

append replaces the cons so why not put the car og your result to the rest of the list. Since you want the result in order I reverse the result in the base case. (can't really tell from the result, but I guessed since you ise append)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top