La libreria racket/match
include la corrispondenza del modello che può utilizzare predicati arbitrari tramite il modello ?
. Insieme a and
, dovresti riuscire a far si che il matcher di Racket si comporti. Anche se sono un po 'debole nel mio OCaml, penso che la seguente traduzione del codice di cui sopra corrisponde il suo significato:
(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")
Il ?
matcher ha un implicito and
incorporato al suo interno, in modo che il codice può essere espresso un po' più succintamente:
(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"]))
in entrambi, le lambda in là non stanno a guardare cosa ma ho abbinato, quindi ho solo chiamato li _
per indicare un non fare-cura. Ma puoi immaginare schemi più sofisticati in cui i predicati potrebbero interessarsi profondamente a ciò che esattamente è stato abbinato.
Eli suggerisce di utilizzare un generale cond
qui, poiché non vi è alcuna corrispondenza significativa del modello nel codice. Sono d'accordo. Il codice sarebbe simile a questo:
(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"]))
L'utilizzo di così tanti '' 'suggerisce che sarebbe espresso meglio con un semplice' cond' ... –