我想使用抽象列表函数创建一个函数,该函数将在没有起始元素的情况下将函数列表应用到彼此上(将起始点设为0)
So'(列表add1 sqr add1)->2
到目前为止,我已经创建了一个列表,列出了这些函数各自的作用,因此对于上面的例子"(1 0 1)
有什么帮助吗?如果你能抽出一个解释就好了,我仍然对文件夹、地图等不确定。
(define (apply_functions lof)
(map (lambda (lof) (lof 0)) lof))
我之前定义了一个复合函数如下,以防它有用?
(define (composite f g)
(lambda (x) (f (g x))))
初始问题是否也可以转换为一个函数,该函数接受函数列表和初始数字(而不是0),并产生数字结果
例如:'(加1 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
,然后返回一个curried函数:
(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
链中的第一个过程(最后一个参数)与作为列表的初始参数一起应用,因此它接受许多参数,而链的其余部分只接受一个参数。