Racket,应用函数列表:抽象列表函数

Racket, applying list of functions: abstract list functions

我想创建一个使用抽象列表函数的函数,它将函数列表相互应用,没有起始元素(起点为 0)

所以 '(list add1 sqr add1) -> 2

到目前为止,我已经创建了一个列表,列出了这些函数单独执行的操作,因此对于上面的示例 '(1 0 1)

有什么帮助吗?如果你能给我一个解释就更好了,我对 foldr、map 等东西仍然犹豫不决

     (define (apply_functions lof)
     (map (lambda (lof) (lof 0)) lof))

我之前定义了一个复合函数如下,以防它有用吗?

     (define (composite f g)
      (lambda (x) (f (g x))))

能否将初始问题也转化为一个函数,该函数接受函数列表和初始数字(0 除外)并产生数字结果

例如: '( add1 sqr sub1) 4 -> 10

编辑::

所以看看这个问题,它想要诸如 (check-expect ((composite-list (list add1 sqr sub1)) 3) 5) 之类的东西,其中起始编号不作为变量包含在内。我已经尝试了多种代码变体,但无法使其正常工作。

这是使用 foldr 的完美情况,它的行为符合预期:

(define (apply-functions lof)
  (foldr (lambda (f acc) (f acc))
         0
         lof))

(apply-functions (list add1 sqr add1))
=> 2

之所以有效,是因为我们从 0 开始依次将每个 f 应用于累积结果。请注意,foldr 以从右到左的顺序应用列表中的函数(即:应用的第一个函数是列表中的最后一个,然后将其结果传递给第二个到-最后一个函数等等)。如果您想强制执行从左到右的顺序,请改用 foldl

对于你问题的最后一部分(编辑后):我们可以通过简单地将正确的参数传递给 foldr 并返回一个柯里化函数来从不同的初始数字开始:

(define ((composite-list lof) init)
  (foldr (lambda (f acc) (f acc))
         init
         lof))

((composite-list (list add1 sqr sub1)) 3)
=> 5

你甚至可以做得比这更一般。您实际上可以进行通用撰写:

(define (my-compose . procedures)
  (let* ((proc-in-order   (reverse procedures))
         (init-proc       (car proc-in-order))
         (remaining-procs (cdr proc-in-order)))
    (lambda g 
      (foldl (lambda (x acc) (x acc))         
             (apply init-proc g)
             remaining-procs))))

;; test first makes a list of it's arguments, 
;; then takes the length, then negates that value
(define test (my-compose - length list))

(test 1 2 3 4) ; ==> -4

链中的第一个过程(最后一个参数)与作为列表的初始参数一起应用,因此它需要很多参数,而链的其余部分只需要一个。