Case Statement Not Assigning Value

一笑奈何 提交于 2019-12-24 08:18:52

问题


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


回答1:


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




回答2:


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.



来源:https://stackoverflow.com/questions/5768696/case-statement-not-assigning-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!