我在调试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
=&gt; 1
,等等)。
答案 0 :(得分:3)
case
使用eqv?
进行匹配。这意味着除了符号,数字,字符,布尔值或空列表之外的任何内容都不会匹配。
在您的情况下,您尝试匹配(非空)列表。那永远不会奏效。 :-((不会匹配字符串或向量。)
答案 1 :(得分:3)
添加到先前的答案(以允许我添加代码的方式):如果您使用的是Racket,您可能会对“匹配”表单感兴趣:
#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)
第二个测试案例说明了如果你真的嫁给了“chars-chars”代表,你将如何使用它。