2011-02-27 14 views
6

acerca de definir-emparejar-expansión, hay materiales raros y códigos de ejemplo para ilustrar los conceptos. Estoy teniendo un momento difícil "decodificar" lo que dice la documentación:define-match-expander

(define-match-expander id proc-expr) 
(define-match-expander id proc-expr proc-expr) 

liga de identificación por un expansor partido.

La primera subexpresión de proc-expr debe evaluar a un transformador que produce una palmada para coincidencia. Cada vez que aparece el id como el comienzo de un patrón, se proporciona este transformador, al tiempo de expansión, un objeto de sintaxis correspondiente al patrón completo (incluido el id). El patrón es el reemplazado con el resultado del transformador .

Un transformador producido por una segunda subexpresión de proc-expr se utiliza cuando se usa id en un contexto de expresión. Usando el segundo proc-expr, id puede ser dando el significado tanto dentro como fuera de los patrones .

¿Alguien puede dar algunos ejemplos de códigos para ilustrar los dos usos del define-match-expander aquí?

Respuesta

5

La idea detrás de match-expander es que puede ampliar el formulario de "coincidencia" para manejar nuevas formas de patrones de su propio diseño.

Por lo tanto, aquí hay una (algo sin sentido) ejemplo que define una forma partido "ABA" que coincide con los patrones de una cosa seguida de otra cosa, seguido de la primera cosa otra vez (por lo tanto, "ABA"):

#lang racket 

(define-match-expander aba 
    (lambda stx 
    (syntax-case stx() 
     [((_ a b)) #'(list a b a)]))) 

(match '(3 4 3) 
    [(aba x y) (printf "x = ~a, y = ~a" x y)]) 

la segunda forma le permite añadir una expansión independiente para ser utilizado fuera de los patrones de los partidos, como esto:

#lang racket 

(define-match-expander aba 
    (lambda stx 
    (syntax-case stx() 
     [((_ a b)) #'(list a b a)])) 
    (lambda stx 
    #'(error "please don't use aba outside of patterns."))) 

(match '(3 4 3) 
    [(aba x y) (printf "x = ~a, y = ~a\n" x y)]) 

(aba x y) 

Advertencia: whuffo el par extra de parens de todo el patrón? No estoy seguro, lo siento.

+1

para que su ejemplo muestra que 1 . si '(3 4 3) coincide con la forma como aba, el nuevo patrón. 2. ¿Puedes explicar cómo funciona el caso de sintaxis? No veo ningún lugar que pueda verificar un formulario. O diga: Supongo que x se une a 3, y se une a 4, pero donde muestra '(3 4 3) satisface el patrón a b a? –

+0

o mi otro entendimiento es que: define-match-expander, define una nueva forma de patrón para ser utilizada en match. El caso de sintaxis, # '(list a b a) está en la posición de la cola, que será la expresión de retorno, que se usa para hacer coincidir' (3 4 3)? si coincide, la x se unirá a 3, y y a 4? ¿Están sucediendo estas cosas para el código de ejemplo? –

+1

Sí, eso suena como un resumen plausible. Disculpas por mi uso del caso de sintaxis en lugar de las reglas de sintaxis más simples; Estoy acostumbrado a usar sintaxis-caso. –

1

Esta es una pregunta muy viejo, pero me gustaría añadir el ejemplo usando "sintaxis de reglas" para el mismo "ABA" patrón:

(define-match-expander aba 
    (syntax-rules() 
    [(aba a b) (list a b a)])) 

(match '(3 4 3) 
    [(aba x y) (printf "x = ~a, y = ~a" x y)]) 

Lado izquierdo (aba a b) es la cosa va en el match, el lado derecho (list a b a) es la sustitución.

(match '(3 4 3) 
    [(aba x y) (printf "x = ~a, y = ~a" x y)]) 

se sustituye por

(match '(3 4 3) 
    [(list x y x) (printf "x = ~a, y = ~a" x y)]) 

La parte buena es que el nuevo matcher funciona para todos "los partidos lo que sea," funciones, como:

(match-define (aba x y) (list 1 2 1)) 
(printf "x = ~a, y = ~a" x y