2012-02-12 89 views
6

由於指南中的所有例子都與名單,我發現很難了解如何使用模式匹配的球拍寫條件匹配像OCaml的那樣,例如:條件模式球拍匹配

read ~var_a var_b s = match s.[0] with 
    | _ when var_b >= var_a + 4 -> 
     (* Do something *) 
    | "a" when is_negative var_b -> 
     (* Do something else *) 
    ... 

我如何在球拍上寫出類似的東西?

謝謝。

回答

10

racket/match庫包括可通過?圖案使用任意的謂詞模式匹配。隨着and,你應該能夠得到球拍的匹配表現。雖然我有點弱,我OCaml中,我覺得上面的代碼下面翻譯匹配它的含義:

(define (my-read #:var-a var-a var-b s) 
    (match (string-ref s 0) 
    [(and _ 
      (? (lambda (_) 
       (>= var-b (+ var-a 4))))) 
    "do something"] 
    [(and '#\a 
      (? (lambda (_) 
       (< var-b 0)))) 
    "do something else"])) 

;; Exercising the first case:  
(my-read #:var-a 50 
     60 "blah") 

;; Exercising the second case: 
(my-read #:var-a 50 
     -40 "alphabet") 

?匹配嵌入了,所以代碼可以表示稍隱式and簡潔爲:

(define (my-read #:var-a var-a var-b s) 
    (match (string-ref s 0) 
    [(? (lambda (_) 
      (>= var-b (+ var-a 4)))) 
    "do something"] 
    [(? (lambda (_) 
      (< var-b 0)) 
     #\a) 
    "do something else"])) 

在這兩個,在那裏lambda表達式不是在看什麼得到了匹配,所以我只是將它們命名爲_來表示不關心。但是你可以想象更復雜的模式,謂詞可以深入地關注匹配的內容。

禮建議使用一般的cond這裏,因爲沒有代碼匹配任何顯著模式。我同意。代碼如下所示:

(define (my-read #:var-a var-a var-b s) 
    (cond 
    [(>= var-b (+ var-a 4)) 
    "do something"] 
    [(and (char=? (string-ref s 0) #\a) 
      (< var-b 0)) 
    "do something else"])) 
+3

使用這麼多'?'表明,它想表達一個普通的更好'cond' ... – 2012-02-12 23:41:34

3

模式匹配可以很容易地轉化爲一系列測試,沒有語言你不能這樣做。

OCaml(可能是Haskell)模式匹配的好處在於,編譯器在可能的情況下將代碼轉換爲最佳測試序列(即,程序不會測試兩次相同的條件,至少在避免警衛)。

+1

我希望,同樣在球拍發生,因爲它有明確的模式匹配capablities,不是嗎? – GiantSquid 2012-02-15 21:32:39

+1

如果你使用'match',可能就是這種情況,但如果你使用'cond'則不會。但我不是Racket的專家,只有OCaml。 – 2012-02-15 22:09:54