Ser*_*lla 6 ocaml functional-programming pattern-matching racket
由于指南中的所有示例都带有列表,我发现很难看到如何在Racket中使用模式匹配来编写像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 *)
...
Run Code Online (Sandbox Code Playgroud)
我如何在Racket中写出类似的东西?
谢谢.
dyo*_*yoo 10
该racket/match库包括模式匹配,可以通过?模式使用任意谓词.与此同时and,你应该能够让Racket的匹配器表现出来.虽然我的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")
Run Code Online (Sandbox Code Playgroud)
该?匹配器有一个隐式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"]))
Run Code Online (Sandbox Code Playgroud)
在这两个中,那里的lambdas没有看到匹配的东西,所以我只是将它们命名_为表示无关紧要.但是你可以想象出更复杂的模式,谓词可以深入关注究竟是什么匹配.
Eli建议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"]))
Run Code Online (Sandbox Code Playgroud)