Aei
Aei

Reputation: 715

Scheme - How to apply a recursive function to a list of variable length

Say I have a function recurse that takes three parameters x,y,z. y and z remain fixed, but x is iterative. I know how to generate a list of x values. How can I write code so that recurse is applied to the list of xs, but y and z remain the same?

I know map works like this but I don't know how to implement it considering it only works on lists of the same size. I do not know what the length of x will be. What I'm trying to do conceptually is call recurse on a list (x1, x2,...,xn) as such:

recurse x1 y z
recurse x2 y z
recurse xn y z

Upvotes: 0

Views: 703

Answers (4)

GoZoner
GoZoner

Reputation: 70155

You have a list '(x1 x2 … xn) and you want to apply a function recurse to each element xn as well as y and z. You haven't said what the return value will be. I will assume there is no return value.

(for-each (lambda (x) (recurse x y z)) <your list of x1, … xn>)

The lambda captures the values for y and z, takes the provided x argument and applies your recurse procedure to all three.

Upvotes: 1

uselpa
uselpa

Reputation: 18917

You can use map:

(define (between x y z) (<= x y z))

(define (between-list xlist y z)
  (map (lambda (e) (between e y z)) xlist))

> (between-list '(1 20 3 100 99 2) 5 15)
'(#t #f #t #f #f #t)

As an alternative to the lambda function used with map, in Racket you can use curryr. Also, if you just do it for side-effects, you can use for-each instead of map:

(define (between x y z) (display (<= x y z)))

(define (between-list xlist y z)
  (for-each (curryr between y z) xlist))

> (between-list '(1 20 3 100 99 2) 5 15)
#t#f#t#f#f#t

Upvotes: 1

GoZoner
GoZoner

Reputation: 70155

Just pass the parameters y and z unchanged:

(define (recurse x y z)
  (unless (null? x)
    ;; … use x, y, z
    ;; then:
    (recurse (cdr x) y z)))

Alternately you can define a helper function; made easy with 'named let`:

(define (recurse x y z)
  (let recursing ((x x))
    ;; … use x, y, z
    ;; then:
    (recursing (cdr x))))

An example:

(define (all-in-range? values min max)
   (or (null? values)
       (and (< min (car values) max)
            (all-in-range? (cdr values) min max))))

Upvotes: 1

Sylwester
Sylwester

Reputation: 48745

You either pass the same variable to the next recursion or you leave it out completely so that it is a free variable.

Eg. send it:

(define (make-list items value)
  (if (zero? items)
      '()
      (cons value (make-list (- items 1) value))))

Have it as a free variable:

(define (make-list items value)
  (let loop ((items items)(acc '()))
     (if (zero? items)
         acc
         (loop (- items 1) (cons value acc)))))

For higher order procedures you also keep it as a free (closed over) variable:

(define (make-list items value)
  (map (lambda (x) value) (range items))) ;; value exists in the anonymous functions scope

Upvotes: 0

Related Questions