#lang scribble/doc @(require scribble/manual scribble/eval "guide-utils.ss" (for-label scheme/match)) @(begin (define match-eval (make-base-eval)) (interaction-eval #:eval match-eval (require scheme/match))) @title[#:tag "match"]{Pattern Matching} The @scheme[match] form supports pattern matching on arbitrary Scheme values, as opposed to functions like @scheme[regexp-match] that compare regular expressions to byte and character sequences (see @secref["regexp"]). @specform[ (match target-expr [pattern expr ...+] ...) ] The @scheme[match] form takes the result of @scheme[target-expr] and tries to match each @scheme[_pattern] in order. As soon as it finds a match, it evaluates the corresponding @scheme[_expr] sequence to obtain the result for the @scheme[match] form. If @scheme[_pattern] includes @deftech{pattern variables}, they are treated like wildcards, and each variable is bound in the @scheme[_expr] to the input fragments that it matched. Most Scheme literal expressions can be used as patterns: @interaction[ #:eval match-eval (match 2 [1 'one] [2 'two] [3 'three]) (match #f [#t 'yes] [#f 'no]) (match "apple" ['apple 'symbol] ["apple" 'string] [#f 'boolean]) ] Constructors like @scheme[cons], @scheme[list], and @scheme[vector] can be used to create patterns that match pairs, lists, and vectors: @interaction[ #:eval match-eval (match '(1 2) [(list 0 1) 'one] [(list 1 2) 'two]) (match '(1 . 2) [(list 1 2) 'list] [(cons 1 2) 'pair]) (match #(1 2) [(list 1 2) 'list] [(vector 1 2) 'vector]) ] The @scheme[struct] construct matches an instance of a particular structure type: @interaction[ #:eval match-eval (define-struct shoe (size color)) (define-struct hat (size style)) (match (make-hat 23 'bowler) [(struct shoe (10 'white)) "bottom"] [(struct hat (23 'bowler)) "top"]) ] Unquoted, non-constructor identifiers in an pattern are @tech{pattern variables} that are bound in the result expressions: @interaction[ #:eval match-eval (match '(1) [(list x) (+ x 1)] [(list x y) (+ x y)]) (match '(1 2) [(list x) (+ x 1)] [(list x y) (+ x y)]) (match (make-hat 23 'bowler) [(struct shoe (sz col)) sz] [(struct hat (sz stl)) sz]) ] An ellipsis, written @litchar{...}, act like a Kleene star within a list or vector pattern: the preceding sub-pattern can be used to match any number of times for any number of consecutive elements of the list of vector. If a sub-pattern followed by an ellipsis includes a pattern variable, the variable matches multiple times, and it is bound in the result expression to a list of matches: @interaction[ #:eval match-eval (match '(1 1 1) [(list 1 ...) 'ones] [else 'other]) (match '(1 1 2) [(list 1 ...) 'ones] [else 'other]) (match '(1 2 3 4) [(list 1 x ... 4) x]) (match (list (make-hat 23 'bowler) (make-hat 22 'pork-pie)) [(list (struct hat (sz styl)) ...) (apply + sz)]) ] Ellipses can be nested to match nested repetitions, and in that case, pattern variables can be bound to lists of lists of matches: @interaction[ #:eval match-eval (match '((! 1) (! 2 2) (! 3 3 3)) [(list (list '! x ...) ...) x]) ] For information on many more pattern forms, see @schememodname[scheme/match]. @close-eval[match-eval]