方案 - 如何将递归函数应用于可变长度列表



假设我有一个函数递归,它接受三个参数x,y,z.y和z保持固定,但x是迭代的。我知道如何生成 x 值的列表。如何编写代码,以便将递归应用于 xs 列表,但 y 和 z 保持不变?

我知道 map 是这样工作的,但我不知道如何实现它,因为它仅适用于相同大小的列表。我不知道x的长度是多少。我在概念上要做的是在列表(x1,x2,...,xn)上调用递归,如下所示:

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

只需将参数传递yz不变:

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

或者,您可以定义一个帮助程序函数;使用"命名let"变得容易:

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

举个例子:

(define (all-in-range? values min max)
   (or (null? values)
       (and (< min (car values) max)
            (all-in-range? (cdr values) min max))))
您可以使用

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)

作为与map一起使用的lambda功能的替代方法,在Racket中您可以使用curryr。另外,如果您只是为了副作用而这样做,则可以使用for-each而不是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

您有一个列表'(x1 x2 … xn),并且您希望将函数recurse应用于每个元素xn以及yz。 你还没有说返回值是什么。 我假设没有返回值。

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

lambda捕获yz的值,获取提供的x参数并将recurse过程应用于所有三个参数。

要么将

相同的变量传递给下一个递归,要么完全省略它,使其成为自由变量。

例如,发送它:

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

将其作为自由变量:

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

对于高阶过程,您还将其保留为自由(闭合)变量:

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

最新更新