Использование Let in Scheme

Я хочу написать программу нахождения корней квадратного уравнения в схему. Я использовал LET для определенных Привязок.

(define roots-with-let
  (λ (a b c)
    (let ((4ac (* 4 a c))
          (2a (* 2 a))
          (discriminant (sqrt ( - (* b b) (4ac)))))
      (cons ( / ( + (- b) discriminant) 2a)
            ( / ( - (- b) discriminant) 2a)))))

я определил дискриминант с 4ac так как я не хочу!--2-->. Даже если я определил (4ac (* 4 a c)), это дает мне эту ошибку:

развернуть: несвязанный идентификатор в модуле в:4ac.

мой вопрос в том, как оценивается let (какой порядок)? А если я захочу ... --1--> в своем let Я должен напишите еще один внутренний let? Есть ли лучший способ сделать это?

4 ответов


использовать let* вместо let.

разницу между let и let* следующий:

let* связывает переменные слева направо. Более ранние привязки можно использовать в новой привязке дальше вправо (или вниз).

let С другой стороны можно рассматривать как синтаксический сахар (или макрос) для простой абстракции лямбда:

(let ((a exp1)
      (b exp2))
   exp)

эквивалентно

((lambda (a b)
    exp)
 exp1 exp2)

  • 4ac-это переменная с числовым значением, поэтому (4ac) не имеет значения.

  • LET связывает все переменные, но переменные не могут использоваться в вычислениях для значений.

Это не работает:

(let ((a 1) (b 1) (c (* a b)))
   c)

использование:

(let ((a 1) (b 1))
  (let ((c (* a b)))
    c))

выше вводит A и B с первым LET. Во втором пусть теперь A и B могут использоваться для вычисления C.

или:

(let* ((a 1) (b 1) (c (* a b)))
   c)

вам понадобится специальные let-строительство (let*) здесь, так как переменные внутри определения let ссылаются друг на друга.

это скорее проблема определения области, чем оценки выражения (в обычном let-определения, порядок оценки не имеет значения, так как значения могут не использовать друг друга)


когда вы используете let, привязки не видны ни в одном из тел. Вместо этого используйте let* и Подробнее см. В документах RNRS.