| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
7.7 Pattern Matching
The (ice-9 match) module provides a pattern matcher,
written by Alex Shinn, and compatible with Andrew K. Wright’s pattern
matcher found in many Scheme implementations.
A pattern matcher can match an object against several patterns and extract the elements that make it up. Patterns can represent any Scheme object: lists, strings, symbols, etc. They can optionally contain pattern variables. When a matching pattern is found, an expression associated with the pattern is evaluated, optionally with all pattern variables bound to the corresponding elements of the object:
(let ((l '(hello (world))))
(match l ;; <- the input object
(('hello (who)) ;; <- the pattern
who))) ;; <- the expression evaluated upon matching
⇒ world
|
In this example, list l matches the pattern ('hello (who)),
because it is a two-element list whose first element is the symbol
hello and whose second element is a one-element list. Here
who is a pattern variable. match, the pattern matcher,
locally binds who to the value contained in this one-element list,
i.e., the symbol world.
The same object can be matched against a simpler pattern:
(let ((l '(hello (world))))
(match l
((x y)
(values x y))))
⇒ hello
⇒ (world)
|
Here pattern (x y) matches any two-element list, regardless of
the types of these elements. Pattern variables x and y are
bound to, respectively, the first and second element of l.
The pattern matcher is defined as follows:
- Scheme Syntax: match exp clause ...
Match object exp against the patterns in the given clauses, in the order in which they appear. Return the value produced by the first matching clause. If no clause matches, throw an exception with key
match-error.Each clause has the form
(pattern body). Each pattern must follow the syntax described below. Each body is an arbitrary Scheme expression, possibly referring to pattern variables of pattern.
The syntax and interpretation of patterns is as follows:
patterns: matches:
pat ::= identifier anything, and binds identifier
| _ anything
| () the empty list
| #t #t
| #f #f
| string a string
| number a number
| character a character
| 'sexp an s-expression
| 'symbol a symbol (special case of s-expr)
| (pat_1 ... pat_n) list of n elements
| (pat_1 ... pat_n . pat_{n+1}) list of n or more
| (pat_1 ... pat_n pat_n+1 ooo) list of n or more, each element
of remainder must match pat_n+1
| #(pat_1 ... pat_n) vector of n elements
| #(pat_1 ... pat_n pat_n+1 ooo) vector of n or more, each element
of remainder must match pat_n+1
| #&pat box
| ($ struct-name pat_1 ... pat_n) a structure
| (= field pat) a field of a structure
| (and pat_1 ... pat_n) if all of pat_1 thru pat_n match
| (or pat_1 ... pat_n) if any of pat_1 thru pat_n match
| (not pat_1 ... pat_n) if all pat_1 thru pat_n don't match
| (? predicate pat_1 ... pat_n) if predicate true and all of
pat_1 thru pat_n match
| (set! identifier) anything, and binds setter
| (get! identifier) anything, and binds getter
| `qp a quasi-pattern
ooo ::= ... zero or more
| ___ zero or more
| ..k k or more
| __k k or more
quasi-patterns: matches:
qp ::= () the empty list
| #t #t
| #f #f
| string a string
| number a number
| character a character
| identifier a symbol
| (qp_1 ... qp_n) list of n elements
| (qp_1 ... qp_n . qp_{n+1}) list of n or more
| (qp_1 ... qp_n qp_n+1 ooo) list of n or more, each element
of remainder must match qp_n+1
| #(qp_1 ... qp_n) vector of n elements
| #(qp_1 ... qp_n qp_n+1 ooo) vector of n or more, each element
of remainder must match qp_n+1
| #&qp box
| ,pat a pattern
| ,@pat a pattern
The names quote, quasiquote, unquote,
unquote-splicing, ?, _, $, and,
or, not, set!, get!, ..., and
___ cannot be used as pattern variables.
Guile also comes with a pattern matcher specifically tailored to SXML
trees, See section sxml-match: Pattern Matching of SXML.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
