Схема сопоставления с образцом - PullRequest
0 голосов
/ 24 февраля 2011

Я написал следующее правило синтаксиса:

(define-syntax match-rewriter  
  (syntax-rules ()
    ((_ (patt body) ...)
     (λ (x) (match x (patt body) ... (_ x))))))

, что, по сути, match-lambda, за исключением того, что оно возвращает свой аргумент, если совпадение не найдено, а не выдает исключение.

Теперь я хочу написать функцию let_as_lambda, которая будет принимать строки исходного кода в качестве входных данных и переписывать операторы let как новую функцию let_as_lambda. Вот что у меня есть:

(define let_as_lambda  
  (match-rewriter (`(let((,<var> ,<val>)) ... ,<expressions>)
                   `((lambda (,<var> ...) ,<expressions>) ,<val> ...))))

Это явно неправильно, как:

(let_as_lambda '(let((x 3)) (+ x 2)))

возвращается:

'((λ ((x) ...) (+ x 2)) (3) ...)

по-прежнему показывает эллипсы и с «3» в скобках. Я считаю, что моя проблема в том, что я не понимаю правильное использование символов `, . и , в сопоставлении с образцом.

Если бы кто-то мог показать мне правильный способ сделать это, это было бы очень признательно.

Спасибо.

1 Ответ

2 голосов
/ 24 февраля 2011

Вы, вероятно, запутались, потому что используете два разных инструмента сопоставления с образцом. Первый - это то, что вы получаете с syntax-rules, а второй - match. Они кажутся достаточно близкими, но есть некоторые важные различия - и в этом случае основная проблема заключается в том, что в отличие от syntax-rules, вы не можете использовать ... в квази-цитируемых результатах match. Поэтому для работы со списками совпадающих значений вам нужно использовать unquote-splicing (или ,@) и другие функции, такие как map и т. Д. Например, сравните результаты этих двух выражений:

(match '(1 2 3) [`(,x ...) `(foo ,x ...)])
(match '(1 2 3) [`(,x ...) `(foo ,@x)])

В качестве примечания было бы неплохо, если бы обычный quasi-quote делал то, что вы хотите, но для полного решения это должно быть возможно и с простыми функциями - и это все усложняет (использование ... нужно будет перевести на apply).

...