【问题标题】:Having trouble with a function in SchemeScheme中的函数有问题
【发布时间】:2015-07-29 14:58:34
【问题描述】:

所以我试图理解这段代码,在盯着它看了太久之后,我决定在这里问是否有人可以帮助我理解它的工作原理和原因

(define knock-knock
 (letrec ([dig (lambda (i)
                 (cons (* i (list-ref knock-knock (- i 1)))
                       (dig (+ i 1))))])
   (cons 1 (dig 1))))

然后按名称调用该函数,其值为:

(list-ref knock-knock 5)

所以我的主要问题是我看不到letrec 的结束位置。另一件事是我没有得到一个列表,那么我应该在第 3 行引用的列表中的第 4 个元素是什么?

【问题讨论】:

  • knock-knock 不是函数。它是一个值,由(cons 1 (dig 1))letrec 中产生。

标签: scheme evaluation evaluation-strategy


【解决方案1】:

首先,请注意:这不是普通的 Scheme,因为它需要惰性求值。

在惰性求值中,仅在需要时才计算值。所以,为了定义knock-knock,我们可以这样做

(cons 1 <thunk: (dig 1)>)

也就是说,我们生成了一对,但我们不需要第二个元素,所以我们将其评估推迟到以后。

当我们真正想要评估第二个元素时,我们已经定义了knock-knock,所以我们可以引用它。

下一个元素是通过获取前一个 (i-1-st) 元素并乘以 i 来计算的。所以这将生成序列 {n!}: 1,1,2,6,24,...

将此代码直接翻译成(通常是惰性的)Haskell 语言如下所示:

knock :: [Int]
knock = 1 : dig 1
    where dig i = (i * knock !! (i-1)) : dig (i+1)

【讨论】:

    猜你喜欢
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    • 2010-09-25
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 2011-03-08
    相关资源
    最近更新 更多