【问题标题】:Scheme - How do I loop an anonymous function?方案 - 如何循环匿名函数?
【发布时间】:2016-10-12 13:49:16
【问题描述】:

我一直在尝试将普通函数转换为执行相同操作的高阶函数。该函数应该将运算符作为参数,然后将该运算符应用于列表中的每个元素。例如,如果我选择运算符“+”,它将返回列表中所有元素的总和。

普通版函数:

(define (accumulate proc id lst)
  (cond ((null? lst) id)
    ((eqv? (cdr lst) '()) (car lst))
    (else (proc (car lst) (accumulate proc id (cdr lst))))))

函数的高阶版本(不完整):

(define (acc-proc proc id)
(lambda (lst)
(cond ((null? lst) id)
      ((null? (cdr lst)) (car lst))
      (else 

在普通函数中,我使用递归调用来循环它,但我不能循环高阶函数,因为它没有 lst 作为参数。相反,参数 lst 在匿名 lambda 过程中。

我是 Scheme 的新手,如果我的解决方案不好,请原谅我。也许有更好的方法可以在不循环的情况下做到这一点?我不知道该在 else 语句中添加什么...

【问题讨论】:

    标签: function loops scheme higher-order-functions anonymous


    【解决方案1】:

    请注意,您的原始函数中有一个错误:您的第二种情况意味着您忽略了 id 的所有内容,除了空列表:

    > (accumulate + 34 '(1 2 3))
    6
    > (accumulate + 34 '())
    34
    

    您只需要两个案例;空列表和非空列表。

    对于实际问题:如果“匿名”部分不是必需的,您可以使用本地命名函数:

    (define (acc-proc proc id)
      (define (recurse lst)
        (if (null? lst)
            id
            (proc (car lst) (recurse (cdr lst)))))
      recurse)
    

    如果匿名很重要,您需要采用 lambda 演算路线并使用定点组合器。

    【讨论】:

    • 这不是错误。第二种情况应该忽略id。如果列表为空,它将返回 id。
    • (累积 + 0 '())
    • @Schytheron 并且任务描述了如果它是像您的代码中那样的空列表之前的步骤会发生什么?
    • 它说:“如果列表中只有一个元素,则应返回第一个元素。如果列表中有多个元素,则应将proc应用于第一个元素并累积结果对于列表的其余部分“
    • @Schytheron 哇。那是......“绝对不标准”(以避免发誓),而不是大多数人期望accumulate 工作的方式。通常,您描述的变体没有身份参数,并且不允许空列表。不过,我相信您可以将我的建议应用到您的解决方案中以符合该规范。
    猜你喜欢
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 2011-11-18
    相关资源
    最近更新 更多