Библиотека 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"]))
В обоих случаях лямбды не наблюдают за совпадениями, поэтому я просто назвал их _
, чтобы обозначить неосторожность.Но вы можете представить себе более сложные шаблоны, в которых предикаты могли бы глубоко заботиться о том, что именно было сопоставлено.
Илай предлагает использовать здесь общий 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"]))