组合其他函数的 Scheme 函数
A Scheme function to compose other functions
我希望创建一个可以将两个函数合二为一的函数。给定 g
和 f
,它应该创建一个函数 h
提供 f
的输出作为 g
的输入。这是我的结果:
(define (compose g f)
(lambda (.args)
(g (apply f (if (atom? .args) (list .args) .args)))))
以下代码段适用于 compose
。
(display ((compose add1 add1) 3))
但是,我不明白为什么下面的示例不起作用。我在下面提供了错误消息,并且我使用的是 Chez Scheme 9.5.2。这里的错误可能与 compose
的可变参数性质有关,但这只是一个想法。有谁知道为什么我的第二次测试没有按预期进行?
(define (reduce f lst seed)
(if (null? lst) seed
(f (car lst) (reduce f (cdr lst) seed))))
(define product-of-incremented-list
(compose
(lambda (lst) (reduce * lst 1))
(lambda (lst) (map add1 lst))))
(display (product-of-incremented-list '(3 4 5)))
; I was expecting 120, because (3 4 5) -> (4 5 6) and (4 5 6) -> 120
; I'm getting an error instead:
; Exception: incorrect number of arguments to #<procedure at compose.scm:285>
您试图使用 .args
表示“参数列表”,也许与 (lambda (x . more) ...)
类比,但这是不正确的。 .args
和其他任何符号一样只是一个符号,因此您编写了一个函数,它接受一个名为 .args
的参数。然后当你发现你的论点是一个列表时,你 (apply f '(3 4 5))
。但是您用于 f
的 lambda 不需要三个参数,它需要一个列表参数。因此错误。
相反,“参数列表”的表达方式是
(lambda args
...)
一般来说,你在lambda后面写的就是如何对待输入参数列表。如果你在那里放一个像 (x y)
这样的列表,那么参数列表应该有两个组成部分,x
和 y
。对于 (x . more)
,第一个元素被命名为 x
,然后列表的其余部分被命名为 more
。如果你只想要列表原样,你只需给它一个名字:这里,args
.
你的第二个问题是检查参数是列表还是原子。这很愚蠢:您可以确定它永远是一个列表,因为您没有分解输入参数。所以,
(define (compose f g)
(lambda args
(f (apply g args))))
我希望创建一个可以将两个函数合二为一的函数。给定 g
和 f
,它应该创建一个函数 h
提供 f
的输出作为 g
的输入。这是我的结果:
(define (compose g f)
(lambda (.args)
(g (apply f (if (atom? .args) (list .args) .args)))))
以下代码段适用于 compose
。
(display ((compose add1 add1) 3))
但是,我不明白为什么下面的示例不起作用。我在下面提供了错误消息,并且我使用的是 Chez Scheme 9.5.2。这里的错误可能与 compose
的可变参数性质有关,但这只是一个想法。有谁知道为什么我的第二次测试没有按预期进行?
(define (reduce f lst seed)
(if (null? lst) seed
(f (car lst) (reduce f (cdr lst) seed))))
(define product-of-incremented-list
(compose
(lambda (lst) (reduce * lst 1))
(lambda (lst) (map add1 lst))))
(display (product-of-incremented-list '(3 4 5)))
; I was expecting 120, because (3 4 5) -> (4 5 6) and (4 5 6) -> 120
; I'm getting an error instead:
; Exception: incorrect number of arguments to #<procedure at compose.scm:285>
您试图使用 .args
表示“参数列表”,也许与 (lambda (x . more) ...)
类比,但这是不正确的。 .args
和其他任何符号一样只是一个符号,因此您编写了一个函数,它接受一个名为 .args
的参数。然后当你发现你的论点是一个列表时,你 (apply f '(3 4 5))
。但是您用于 f
的 lambda 不需要三个参数,它需要一个列表参数。因此错误。
相反,“参数列表”的表达方式是
(lambda args
...)
一般来说,你在lambda后面写的就是如何对待输入参数列表。如果你在那里放一个像 (x y)
这样的列表,那么参数列表应该有两个组成部分,x
和 y
。对于 (x . more)
,第一个元素被命名为 x
,然后列表的其余部分被命名为 more
。如果你只想要列表原样,你只需给它一个名字:这里,args
.
你的第二个问题是检查参数是列表还是原子。这很愚蠢:您可以确定它永远是一个列表,因为您没有分解输入参数。所以,
(define (compose f g)
(lambda args
(f (apply g args))))