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).
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:
The second test case illustrates how you might use this if you're really married to the "list-of-chars" representation.
case
does matching usingeqv?
. 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.)