我正在经历“计算机程序的结构和解释”,并且在其中一项练习中遇到了一些麻烦( 2.1 )。我正在以R5RS模式进行编码。

这是我的代码:

(define (make-rat n d) 
  (let (((c (gcd n d))
         (neg (< (* n d) 0))
         (n (/ (abs n) c))
         (d (/ (abs d) c)))
        (cons (if neg (- n) n) d))))

这是Drracket给我的错误消息:

let: bad syntax (not an identifier and expression for a binding) in: ((c (gcd n d)) (neg (< (* n d) 0)) (pn (/ (abs n) c)) (pd (/ (abs d) c)))

我想我已经搞砸了,让我们的语法。但是我不确定如何解决。

有帮助吗?

解决方案

如您的编辑指示,您正在过早使用C标识符。 (这就是为什么它在修复了额外括号的语法问题后不起作用的原因。)“让”中的标识符彼此看不到。您需要在第一个筑巢的第一个lets嵌套。

    (let ((c (gcd ...)))
      (let ((...))
        exps ...))

我不记得SICP何时介绍其他LET表格,但是如果您使用大量嵌套的LETS卡住,则可以使用 let* 其中每个后续标识符处于所有先前的范围。也就是说,以下两个定义是等效的:

(define foo
  (let* ((a 1)
         (b (+ 1 a))
         (c (+ 1 b)))
    (+ 1 c)))

(define foo
  (let ((a 1))
    (let ((b (+ 1 a)))
      (let ((c (+ 1 b)))
        (+ 1 c)))))

不幸的是,对于初学者而言,不同的let表格的范围可能有点多。

其他提示

我围绕变量声明添加了一组额外的括号。

另外,由于我使用c定义n和d,所以我必须更改为让*使其正常工作

我的固定代码:

(define (make-rat n d) 
  (let* ((c (gcd n d))
         (neg (< (* n d) 0))
         (n (/ (abs n) c))
         (d (/ (abs d) c)))
        (cons (if neg (- n) n) d)))

试试这个:

(define (make-rat n d)
  (let ([c (gcd n d)]
        [neg (< (* n d) 0)]
        [n (/ (abs n) c)]
        [d (/ (abs d) c)])
    (cons (if neg
              (- n)
              n) 
          d)))
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top