【问题标题】:Cannot understand how we can give a procedures as actual parameter when formal parameters are used as values in scheme?无法理解当形式参数用作方案中的值时,我们如何将过程作为实际参数?
【发布时间】:2016-07-13 20:18:55
【问题描述】:

在 SICP 练习 1.37 中

Section 1.3.3 in SICP 向下滚动到本节末尾(就在 1.3.4 之前)以查找练习 [本节中的第三个练习]。

根据问题,我将 cont-frac 定义为

(define (cont-frac n d k)
    (if (= k 0)
     0 
     (/ n (+ d (cont-frac n d (- k 1))))
    )
)

Link to solution for the exercise

根据解决方案链接,上面的代码似乎是一致的。 当 n 和 d 被替换为 (lamda (i) 1.0) 时,问题出现在解决方案的第二部分,在解决方案的 (a) 部分,这是一个过程。

我无法理解在cont-frac 的过程中替换时这将如何工作。当我尝试时,出现错误提示 Wrong type of argument


编辑 1

我已经添加了我的整个解决方案。它解决了问题,但没有抓住该部分的本质。这是练习 1.37、1.38 和 1.39 的解法。 该程序不使用Procedure as General Method,以下链接的解决方案使用Solution to 1.37Solution to 1.38Solution to 1.39

在下面的程序中
在程序phie-2-val 中,k 是连分数的步数
在程序tan中,k是以弧度为单位的角度(精确值的步数为1000)

#!/usr/local/bin/guile \
-e main -s
!#
(define (finite-cont-frac n d k)
    (if (= k 0)
        0 
        (/ n (+ d (finite-cont-frac n d (- k 1))))))

(define (e-2 n d k1 c k)
    (define (d-val) 
        (if (= (modulo k1 3) 1)
            (+ c 2)
            1))
    (define (c-val)
        (if (= (d-val) 1) c (d-val)))
    (if (= k 0)
        0 
        (/ n (+ (d-val) (e-2 n (d-val) (+ k1 1) (c-val) (- k 1))))))

(define (tan-cf n k d k1)
    (define (d-val)
        (if (= k1 0) 1 (+ d 2)))
    (if (= k 0) 
        0
        (/ n (+ (d-val) (tan-cf n (- k 1) (d-val) (+ k1 1))))))

(define (tan-man x kk)
    (let ((a (- (* x x))))
        (tan-cf a kk 1 0)))
(define rrr 80.0)
(define (main args)
    (let* ((k (string->number (list-ref args 1)))
           (phi (/ 1.0 (finite-cont-frac 1.0 1.0 k)))
           (e-2-val (e-2 1.0 1 0.0 0 k))
           (tt (/ (tan-man k 1000) (- 0.0 k))))
        (display tt)
        (newline)))

【问题讨论】:

  • 请注意,右括号不应该像 C 编程花括号一样在自己的行上。它们应该在最后一个右括号旁边的上一行。
  • 它像一个惯用规则吗?因为这不会给出任何错误。
  • TL;DR 这是共识。 确实不影响解释。您可以在每一行上使用一个符号或括号,使您的示例有几页长的一行不可读但完全可运行的代码。 Lisp 在其代码中几乎没有结构,因此您如何设计代码就是如何使其具有可读性。lisper 同意 style guides 并在 PSE 上提出问题
  • 好的,我明白了。感谢您的风格指南。

标签: scheme sicp mit-scheme continued-fractions


【解决方案1】:

链接的答案看起来错误,您应该传递程序,而不是数字作为实际参数。使用名为accumulate 的帮助程序:

(define (accumulate combiner null-value term1 term2 a next b)
  (if (> a b)
      null-value
      (combiner (term1 a)
                (term2 a)
                (accumulate combiner
                            null-value
                            term1
                            term2
                            (next a)
                            next
                            b))))

(define (cont-frac n d k)
  (accumulate (λ (x y rec) (/ x (+ y rec)))
              0 n d 1 add1 k))

现在我们可以按预期调用该过程了:

(cont-frac (lambda (i) 1.0)
           (lambda (i) 1.0)
           10)
=> 0.6179775280898876

【讨论】:

  • 我刚刚意识到我犯了什么错误并返回到 stackoverflow 删除问题。不过感谢您的解决方案。
  • 链接的答案是正确的。我的解决方案不适合该部分。我的解决方案在某种意义上没有错,但链接中的解决方案使用 n 和 d 作为过程,将 k 作为参数传递。链接中的解决方案非常通用,我不得不编写很多其他程序来定义练习 1.38 和 1.39 中的 n 和 d,但是使用链接的通用解决方案,传递 λ 函数就足够了。
猜你喜欢
  • 2017-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-25
  • 2017-12-28
  • 2019-01-27
  • 1970-01-01
  • 2013-01-16
相关资源
最近更新 更多