【问题标题】:non explicit recursion in scheme方案中的非显式递归
【发布时间】:2013-11-29 15:50:44
【问题描述】:

我需要一些帮助来仅使用抽象列表函数在方案中进行递归。例如,我将如何使用显式递归更改此代码,使其主体中没有函数名称:

(define (make_unique_list lst) 
  (cond
    [(empty? lst) empty]
    [(member? (first lst) (rest lst)) (make_unique_list (rest lst))]
    [else (cons (first lst) (make_unique_list (rest lst)))]))

谢谢!

【问题讨论】:

    标签: recursion scheme


    【解决方案1】:

    在 R6RS 方案中:

    (import (rnrs) (rnrs lists))
    
    (define (make-unique-list lst)
      (reverse
       (fold-left
        (lambda (r e) (if (member e r) r (cons e r)))
        '()
        lst)))
    
    (display (make-unique-list '(1 2 3 4 3 5 6 3 2 1 7)))
    => {1 2 3 4 5 6 7}
    

    在球拍中:

    (define (make-unique-list lst)
      (reverse
       (foldl
        (lambda (e r) (if (member e r) r (cons e r)))
        '()
        lst)))
    

    (define (make-unique-list lst)
      (reverse
       (for/fold ((r '())) ((e (in-list lst)))
         (if (member e r) r (cons e r)))))
    

    请注意,在前 2 个示例中,我使用了 reversefoldl / fold-left,而不是 foldrfold-right(自己尝试一下,看看为什么)。

    顺便说一句,这个程序通常称为remove-duplicates,并且内置在 Racket 中:

    (remove-duplicates '(1 2 3 4 3 5 6 3 2 1 7))
    

    【讨论】:

      【解决方案2】:

      这看起来像fold 可以使用。通过将cond中的非空情况的逻辑组合到一个累加函数中,我们可以选择性地累加列表中我们还没有看到的项目。

      回想一下给fold的函数有两个参数:一个是当前项,另一个是当前累加值。在这种情况下,当前项将是 X 类型,当前累积值将是 X 的列表。函数需要返回 X 的列表。

      如果您需要保留输入列表的顺序,请谨慎选择 fold-rightfold-left 或您环境中的等效项。

      【讨论】:

        【解决方案3】:

        可以使用所谓的Y combinator 在Scheme 中表达匿名的递归函数。我自己没有使用过,但这主要是因为它有点难以理解。不过很有用。

        另见:https://en.wikipedia.org/wiki/Fixed-point_combinator

        【讨论】:

        • “非显式”,即隐式递归通常意味着折叠。通过 Y 的递归仍然是递归,那里仍然有一个函数调用,例如Y (λ fact.λ n.n < 2 ? 1 ; n*fact(n-1))。虽然是匿名的,但它仍然是一个递归。 :)
        • @WillNess 你是对的 - 我可能误解了这个问题。不过,使用 Y 型梳子。您没有明确使用问题中提到的任何函数 name
        • 我们使用fact...只是那个函数fact是Y当场为我们创建的。不是一些全局函数;仍然,一个功能。 :)
        • 我必须同意赫尔曼的观点。 Y 组合器仍然是某种隐式递归。 Y 组合器听起来像 fold 一样的高阶函数。
        • @LoïcFaure-Lacroix foldNat (λ n.λ r.n*r) 1:看不到函数调用。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-19
        • 2023-04-03
        • 2020-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多