[racket] matching behavior in dispatch-rules
If you run this code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket
(require web-server/dispatch
web-server/http/request-structs
net/url)
(define (url->request u)
(make-request #"GET" (string->url u) empty
(delay empty) #f "1.2.3.4" 80 "4.3.2.1"))
(define-values (test-dispatch sum-url)
(dispatch-rules
[((? string?) "foo" (? string?)) test-route]
[((? string?) (? (λ(x) (equal? x "bar"))) (? string?)) test-route]))
(define (test-route req . args)
(displayln (format "args = ~v" args)))
(test-dispatch (url->request "http://url.com/first-string/foo/second-string.html"))
(test-dispatch (url->request "http://url.com/first-string/bar/second-string.html"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
You'll get this:
args = '("first-string" "second-string.html")
args = '("first-string" "bar" "second-string.html")
Whereas if you use these patterns with regular match, like so:
(match (list "first-string" "foo" "second-string.html")
[(and matched (list (? string?) "foo" (? string?))) matched])
(match (list "first-string" "bar" "second-string.html")
[(and matched (list (? string?) (? (λ(x) (equal? x "bar"))) (? string?))) matched])
You'll get:
'("first-string" "foo" "second-string.html")
'("first-string" "bar" "second-string.html")
Thus my question: why doesn't the literal "foo" in the first pattern under dispatch-rules become one of the matched items, as it does with regular match?