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
链中的第一个过程(最后一个参数)与作为列表的初始参数一起应用,因此它需要很多参数,而链的其余部分只需要一个。
我想创建一个使用抽象列表函数的函数,它将函数列表相互应用,没有起始元素(起点为 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
链中的第一个过程(最后一个参数)与作为列表的初始参数一起应用,因此它需要很多参数,而链的其余部分只需要一个。