I just wrote a match-expander that does something like that:
(check-equal? (match 1 [(my-pat n:num) n]) 1)
(check-equal? (match 'x [(my-pat n:num) n] [_ 2]) 2)
like this:
#lang racket
(require rackunit)
(require (for-syntax
(only-in lang/htdp-intermediate-lambda
string-contains?)
racket/string
racket/match))
(define-match-expander my-pat
(lambda (stx)
(syntax-case stx ()
[(my-pat pat)
(let* ([pat-sym (syntax->datum #'pat)]
[pat-str (symbol->string pat-sym)])
(cond [(not (string-contains? ":" pat-str))
#'pat]
[else
(parse-pat-str pat-str stx)]))])))
(define-for-syntax (parse-pat-str pat-str stx)
(let ([split-pat (string-split pat-str ":")])
(match split-pat
[(list pat-name-str type-str)
(with-syntax ([type-pred (type-str->stx-type-pred type-str)]
[pat-name (datum->syntax stx (string->symbol pat-
name-str))])
#'(? type-pred pat-name))])))
(define-for-syntax (type-str->stx-type-pred type-str)
(match type-str
["num" #'number?]
["str" #'string?]
["lst" #'list?]))
(check-equal? (match 1 [(my-pat n:num) n]) 1)
(check-equal? (match 'x [(my-pat n:num) n] [_ 2]) 2)
(check-equal? (match "string" [(my-pat s:str) s]) "string")
(check-equal? (match 'x [(my-pat s:str) s] [_ 2]) 2)
(check-equal? (match (list 1 2 3) [(my-pat l:lst) l]) (list 1 2 3))
(check-equal? (match 'x [(my-pat l:lst) l] [_ 2]) 2)
On Dec 26, 2013, at 2:45 PM, Jens Axel Søgaard wrote:
The match pattern (? number? n) matches number and
binds it to n.
(match 1 [(? number? n) n])
1
I'd like to write (match 1 [n:num n]) instead.
Since there is no define-identifier-match-expander I have
tried to make (match 1 [(n:num) n]) work. I need a hint.
Here is a non-working attempt:
(define-match-expander n:num
(λ(stx)
(syntax-case stx ()
[(id)
(with-syntax ([n (syntax/loc #'id n)])
#'(? number? n))])))
(check-equal? (match 1 [(n:num) n]) 1)
(check-equal? (match 'x [(n:num) n] [_ 2]) 2)
/Jens Axel
--
Jens Axel Søgaard
____________________
Racket Users list:
http://lists.racket-lang.org/users
____________________
Racket Users list:
http://lists.racket-lang.org/users