微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

组成其他功能的Scheme功能

如何解决组成其他功能的Scheme功能

我希望创建一个可以将两个功能组合为一个功能。给定gf,它应该创建一个函数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)的列表,则参数列表应该是两个组成部分,xy。对于(x . more),第一个元素命名为x,然后列表的其余部分命名为more。如果您只是想按原样列出,只需给它起一个名字:args

第二个问题是这种检查参数是列表还是原子。这很愚蠢:您可以确定它始终是列表,因为您不会分解输入参数。所以,

(define (compose f g)
  (lambda args
    (f (apply g args))))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。