Case Statement Not Assigning Value

2019-08-04 03:13发布

I'm having some trouble debugging a case statement. I was hoping that the statement would assign numeric values to note-val, but so far it is assigning #<void>. I know it's something wrong with the case statement, because if I add an else clause, that value gets applied. Given a sample input of '(((#\3 #\A) (#\4 #\B)) ((#\4 #\C))), what am I doing wrong here? (In regards to the case statement. I'm sure there are other errors, but I'd like to try to work those out myself if I can get this fixed.)

(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))
              '()))))

Oh, and char->int is a tiny utility function I wrote that pretty much does what it says in the name (#\1 => 1, and so on).

2条回答
贪生不怕死
2楼-- · 2019-08-04 03:33

To add to the prior answer (in a way that allows me to add code): if you're using Racket, you might be interested in the "match" form:

#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)

The second test case illustrates how you might use this if you're really married to the "list-of-chars" representation.

查看更多
仙女界的扛把子
3楼-- · 2019-08-04 03:34

case does matching using eqv?. That means that anything other than symbols, numbers, characters, booleans, or the empty list will never match.

In your case, you were trying to match (non-empty) lists. That will never work. :-( (Neither will matching strings or vectors work.)

查看更多
登录 后发表回答