2011-04-24 72 views
1

我在調試case語句時遇到了一些麻煩。我希望這個陳述會給note-val分配一個數值,但是到目前爲止它是分配#<void>。我知道case語句有些問題,因爲如果我添加一個else子句,那麼就會應用該值。給定樣本輸入'(((#\3 #\A) (#\4 #\B)) ((#\4 #\C))),我在這裏做錯了什麼? (在關於case語句。我敢肯定有其他錯誤的,但我想嘗試的工作出那些自己,如果我能得到這個固定的。)沒有指定值的案例陳述

(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,等等)。

回答

3

case確實匹配使用eqv?。這意味着符號,數字,字符,布爾值或空列表之外的任何內容都不會匹配。

就你而言,你試圖匹配(非空)列表。這將永遠不會工作。 :-((匹配的字符串或向量都不起作用)

+0

嘛,狗屎感謝擡頭。你知道另一種方法去解決這個問題嗎,或者我堅持使用嵌套'if's的醜陋階梯? – Andy 2011-04-24 05:16:41

+2

@Andrew:你可以使用'cond' .--) – 2011-04-24 05:16:59

+1

A-ha!先生,你真棒。 – Andy 2011-04-24 05:24:13

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) 

第二個測試案例說明,如果你真的嫁給你怎麼可能用這種‘列表中,字符’表示