#lang scheme (define-syntax :: (lambda (stx) (raise-syntax-error ':: "dont use this"))) #| x :: bs -> (list x . bs) x :: a :: b -> (list x a . b) |# (define-syntax (list-match stx) (define (fixup-pattern pattern) (syntax-case pattern (::) [(head :: tail) (with-syntax ([head (fixup-pattern #'head)] [tail (fixup-pattern #'tail)]) #'(list-rest head tail))] [(head :: tail :: rest ...) (with-syntax ([head (fixup-pattern #'head)] [tail (fixup-pattern #'tail)] [(_ rest ...) (fixup-pattern #'(rest ...))]) #'(list-rest head tail rest ...))] [(x) #'(list-rest x)] [x (identifier? #'x) #'x] [else (raise-syntax-error 'fixup-pattern "unknown pattern" (syntax->datum pattern))] )) (syntax-case stx () [(_ expr (pattern result) ...) (with-syntax ([(updated-pattern ...) (map fixup-pattern (syntax->list #'(pattern ...)))]) #'(match expr (updated-pattern result) ...))])) (list-match '(1 2 3) [(a :: b) (and (equal? a 1) (equal? b '(2 3)))]) (list-match '(1 2 3 4) [(a :: b :: c) (and (equal? a 1) (equal? b 2) (equal? c '(3 4)))]) (list-match '((1 2) (3 4)) [((a :: b) :: c) (and (equal? a 1) (equal? b '(2)) (equal? c '((3 4))))]) (list-match '(1 2 3) [(a :: b :: c :: null) (and (equal? a 1) (equal? b 2) (equal? c 3))]) (list-match 1 [(a) (and (equal? a 1))])