Ситуация, не присваивающая значение - PullRequest
1 голос
/ 24 апреля 2011

У меня проблемы с отладкой оператора case. Я надеялся, что оператор присваивает числовые значения note-val, но пока он присваивает #<void>. Я знаю, что с оператором case что-то не так, потому что, если я добавлю предложение else, это значение будет применено. Учитывая пример ввода '(((#\3 #\A) (#\4 #\B)) ((#\4 #\C))), что я здесь не так делаю? (Что касается описания случая. Я уверен, что есть и другие ошибки, но я хотел бы попытаться устранить их самостоятельно, если смогу исправить это.)

(define (calc-freqs chord)
  (let ((octave (char->int (caaar chord)))
        (note-val (case (cdaar chord)
                    [((#\B #\#) (#\C))      0]
                    [((#\C #\#) (#\D #\b))  1]
                    [((#\D))                2]
                    [((#\D #\#) (#\E #\b))  3]
                    [((#\E) (#\F #\b))      4]
                    [((#\E #\#) (#\F))      5]
                    [((#\F #\#) (#\G #\b))  6]
                    [((#\G))                7]
                    [((#\G #\#) (#\A #\b))  8]
                    [((#\A))                9]
                    [((#\A #\#) (#\B #\b)) 10]
                    [((#\B) (#\C #\b))     11])))
    (cons (* a4 (expt 2 (+ (- octave 4) (/ (- note-val 9) 12))))
          (if (pair? (cdr chord))
              (calc-freqs (cdr chord))
              '()))))

Да, и char->int - это крошечная служебная функция, которую я написал, которая в значительной степени выполняет то, что написано в имени (#\1 => 1 и т. Д.).

Ответы [ 2 ]

3 голосов
/ 25 апреля 2011

Чтобы добавить к предыдущему ответу (таким образом, чтобы я мог добавить код): если вы используете Racket, вас может заинтересовать форма "match":

#lang racket

(require rackunit)

(define (pitchclass->half-steps pitchclass)
  (match pitchclass
    [(or "B#" "C")   0]
    [(or "C#" "Db")  1]
    ["D"             2]
    [(or "D#" "Eb")  3]
    [(or "E" "Fb")   4]
    [(or "E#" "F")   5]
    [(or "F#" "Gb")  6]
    ["G"             7]
    [(or "G#" "Ab")  8]
    ["A"             9]
    [(or "A#" "Bb") 10]
    [(or "B" "Cb")  11]))

;; TEST CASES:

(check-equal? (pitchclass->half-steps "Ab") 8)
(check-equal? (pitchclass->half-steps (apply string '(#\D #\#))) 3)

Второй тестовый пример иллюстрирует, как вы можете использовать это, если вы действительно женаты на представлении «список символов».

3 голосов
/ 24 апреля 2011

case выполняет сопоставление, используя eqv?. Это означает, что все, кроме символов, чисел, символов, логических значений или пустого списка, никогда не будет совпадать.

В вашем случае вы пытались сопоставить (не пустые) списки. Это никогда не сработает. :-( (Соответствующие строки или векторы не будут работать.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...