определить-матч-расширитель - PullRequest
6 голосов
/ 28 февраля 2011

о define-match-extension, есть редкие материалы и примеры кодов для иллюстрации концепций.Мне трудно "расшифровать" то, что написано в документации:

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

Привязывает id к расширителю совпадений.

Первое подвыражение proc-expr должно быть оценено кактрансформатор, который производит похлопывание для матча.Всякий раз, когда идентификатор появляется как начало шаблона, этот преобразователь получает во время раскрытия объект синтаксиса, соответствующий всему шаблону (включая идентификатор).Шаблон заменяется результатом преобразования.

Преобразователь, созданный вторым подвыражением proc-expr, используется, когда id используется в контексте выражения.Используя второй proc-expr, id может быть задан как внутри, так и снаружи шаблонов.

Кто-нибудь может привести несколько примеров кодов, чтобы проиллюстрировать здесь два использования define-match-expander?

Ответы [ 2 ]

5 голосов
/ 28 февраля 2011

Идея экспандера совпадений состоит в том, что вы можете расширить форму «совпадения» для обработки новых шаблонных форм вашего собственного дизайна.

Итак, вот (несколько бессмысленный) пример, который определяет форму соответствия «aba», которая соответствует шаблонам одной вещи, за которой следует другая вещь, за которой следует первое (опять же, «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)])

Вторая форма позволяет вам добавить отдельное расширение, которое будет использоваться вне шаблонов совпадений, например:

#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)

Предостережение: что за дополнительная пара скобок вокруг шаблона?Не уверен, извините.

1 голос
/ 07 января 2018

Это действительно старый вопрос, но я бы хотел добавить пример, используя "синтаксические правила" для того же шаблона "aba":

(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)])

Левая сторона (aba a b) - это то, что входит в match, правая сторона (list a b a) - это замена.

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

заменяется на

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

Приятной особенностью является то, что новый механизм сопоставления работает для ВСЕХ функций «сопоставления с чем угодно», таких как:

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