Проблема с синтаксисом «Пусть» в схеме
Вопрос
Я прохожу через «структуру и интерпретацию компьютерных программ», и у меня есть немного неприятностей, выполняя одно из упражнений ( 2.1 ). Я кодирую в Drracket в режиме 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 преждевременно. (Вот почему он не работает после исправления проблемы синтаксиса дополнительных скобок.) Идентификаторы в «Пусть» не видят друг друга. Вам нужно было гнездить вашим вторым трем, давайте под первым.
(let ((c (gcd ...)))
(let ((...))
exps ...))
Я не вспоминаю, когда / если siCP представляют другие формы, но если вы застряли, используя много вложенных, вы можете использовать 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)))))
Правила охвата различных путей формы могут быть немного для новичка, к сожалению.
Другие советы
Я добавил дополнительный набор скобок вокруг переменных объявлений, упс.
Кроме того, поскольку я использовал 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)))