【问题标题】:A Scheme function to compose other functions用于组合其他函数的 Scheme 函数
【发布时间】:2020-11-12 18:13:35
【问题描述】:

我希望创建一个可以将两个函数合二为一的函数。给定gf,它应该创建一个函数h 提供f 的输出作为g 的输入。这是我的结果:

(define (compose g f)
    (lambda (.args)
        (g (apply f (if (atom? .args) (list .args) .args)))))

以下 sn-p 适用于 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>

【问题讨论】:

    标签: scheme variadic-functions anonymous-function function-composition chez-scheme


    【解决方案1】:

    您试图使用.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))))
    

    【讨论】:

      猜你喜欢
      • 2013-01-06
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      • 2017-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多