La biblioteca racket/match
incluye coincidencia de patrones que puede utilizar predicados arbitrarios a través del patrón ?
. Junto con and
, deberías poder hacer que el emparejador de Racket se comporte. Aunque estoy un poco débil en mi OCaml, creo que la siguiente traducción del código anterior coincide con su significado:
(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")
El matcher ?
tiene una implícita and
incrustado dentro de ella, así que el código se puede expresar un poco más sucintamente como:
(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"]))
en tanto, las lambdas en que no están viendo lo que se interpuso coincidentes, por lo que sólo ellos, llamado _
para denotar una de no importa. Pero se pueden imaginar patrones más sofisticados en los que los predicados podrían interesarse por lo que exactamente se combinó.
Eli sugiere usar aquí un cond
general, ya que no hay ninguna coincidencia de patrones significativa en el código. Estoy de acuerdo. El código se vería así:
(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"]))
El uso de tantos '?' Sugiere que se expresaría mejor con un simple 'cond' ... –