Thư viện racket/match
bao gồm đối sánh mẫu có thể sử dụng các biến vị ngữ tùy ý thông qua mẫu ?
. Cùng với and
, bạn sẽ có thể nhận được Racket của matcher để cư xử. Mặc dù tôi là một chút yếu trong OCaml của tôi, tôi nghĩ rằng bản dịch sau đây của mã trên phù hợp với ý nghĩa của nó:
(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")
Các ?
khớp có tiềm ẩn and
nhúng trong nó, vì vậy các mã có thể được bày tỏ một chút hơn ngắn gọn như sau:
(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"]))
trong cả hai, các lambdas trong đó không được xem những gì đã xuất hiện, vì vậy tôi chỉ đặt tên cho chúng _
để biểu thị một đừng chăm sóc. Nhưng bạn có thể tưởng tượng ra các mô hình phức tạp hơn, nơi các vị từ có thể quan tâm sâu sắc về những gì chính xác đã khớp.
Eli đề nghị sử dụng tổng quát cond
tại đây, vì không có bất kỳ kết hợp mẫu quan trọng nào trong mã. Tôi đồng ý. Mã sẽ trông giống như sau:
(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"]))
Sử dụng quá nhiều '? 'Gợi ý rằng nó sẽ được thể hiện tốt hơn với một cụm từ' cond' đơn giản ... –