将功能列表应用于球拍中的值列表

时间:2019-03-08 21:35:13

标签: lambda functional-programming scheme racket

我一般对球拍和方案语言都不熟悉,我很难实现自己的想法。

基本上,我有一个函数列表(叫它List f)和一个字符串列表(叫它List s)。我需要为f中的每个函数执行该函数,并将值存储在另一个列表中(让调用为List done)。

例如:假设我有List A = (f1 f2)List B = (a b c),我将执行:

f1 a
f1 b
f1 c
f2 a
f2 b
f2 c

他们都将其值附加到List done

我也不能在球拍中使用任何形式的set

我了解这是应该如何工作的,并且可以轻松地用C或Java编写代码,但是方案给我带来了麻烦。

1 个答案:

答案 0 :(得分:3)

在Racket中,有许多内置过程可轻松解决涉及操纵列表的问题。对于您的示例,您正在寻找for*/list

(define A (list string-upcase string-downcase))
(define B (list "Aa" "Bb" "Cc"))

(define done
  (for*/list ([f A] [s B])
    (f s)))

遍历A中的所有元素,依次将每个元素分配给变量f。并且在嵌套循环中,它还会迭代B中的所有元素,依次将每个元素分配给变量s。在循环的主体中,它将每个f应用于所有s,并在输出列表中收集所有内容。现在done包含期望值:

done
=> '("AA" "BB" "CC" "aa" "bb" "cc")

如果我们要使用递归手动完成此操作,则将需要更多工作。可能的实现方式是使一个过程执行“外部”循环,这将调用另一个过程进行“内部”循环。第三个过程将启动递归并合并结果:

(define (outer-loop funcs params)
  (if (null? funcs)
      '()
      (cons (inner-loop (car funcs) params)
            (outer-loop (cdr funcs) params))))

(define (inner-loop f params)
  (if (null? params)
      '()
      (cons (f (car params))
            (inner-loop f (cdr params)))))

(define (apply-funcs funcs params)
  (apply append ; required to "flatten" the list of lists
         (outer-loop funcs params)))

我们将像这样使用它:

(define done (apply-funcs A B))

首先,您应该学习如何通过实现自己的循环来手动解决列表问题。一旦确信自己了解自己在做什么,就花一些时间来学习现有的list proceduresiterations and comprehensions,这是在现实生活中使用该语言的惯用方式。