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

Я пытаюсь написать сопоставление с шаблоном для звонков, чтобы разрешить подобное:

(define let→λ&call
  (match-lambda (`(let ((,<var> ,<val>) . (,<vars> ,<vals>)) ,<expr> . ,<exprs>)
                   `((λ ,<var> . ,<vars> . ,<expr> . ,<exprs>) ,<val> . ,<vals>))))

Но у меня две проблемы, которые я не могу решить.

1) Интерпертержалуется на "."в:

,<expr> . ,<exprs>

в соответствующем разделе

2) Вызывает let → λ & call (с удалением "."), как:

(let→λ&call ((x 1) (y 2) (z 3)) (displayln x) (displayln y) (displayln z))

get aжалоба на ссылку на идентификатор «x» перед его определением, что кажется неизбежным.

Любой совет приветствуется.

Спасибо.


Хорошо, здесьэто полная, более интересная проблема.

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

Используя переписчик совпадений, я хочу написать правила, которые можно передать другой функции переписать , например:

#| (rewrite rule s) repeatedly calls unary function 'rule' on every "part" 
    of s-expr s, in unspecified order, replacing each part with result of rule, 
    until calling rule makes no more changes to any part. 
     Parts are s, elements of s, and (recursively) parts of the elements of s. (define (rewrite rule s) |#

  (let* ([with-subparts-rewritten
          (if (list? s) (map (λ (element) (rewrite rule element)) s) s)]
         [with-also-rule-self (rule with-subparts-rewritten)])
    (if (equal? with-also-rule-self with-subparts-rewritten)
        with-also-rule-self
        (rewrite rule with-also-rule-self))))

Вот пример правильного использования:

(define arithmetic 
   (match-rewriter (`(+ ,a ,b) (+ a b)) 
                (`(* ,a ,b) (* a b)) 
                ))
(rewrite arithmetic '(+ (* 2 (+ 3 4)) 5))

==>

19

Теперь я написал:

(define let→λ&call
  (match-rewriter (`(let ((,<var> ,<val>) . (,<vars> ,<vals>)) ,<expr> . ,<exprs>)
                   `((λ (,<var> . ,<vars>) ,<expr> . ,<exprs>) ,<val> . ,<vals>))))

для реализации let как лямбда-вызовов, но так оно и ведет себя:

(rewrite let→λ&call '(let((x 1) (y 2) (z 3)) (displayln x) (displayln y) (displayln z)))
'((λ (x y 2)
    (displayln x)
    (displayln y)
    (displayln z))
  1
  z
  3)

, что, я должен сказать, действительно поставило меня в тупик.Странно этот вызов:

(rewrite let→λ&call '(let((w 0) (x 1) (y 2) (z 3)) (displayln w) (displayln x) (displayln y) (displayln z)))
'(let ((w 0) (x 1) (y 2) (z 3))
   (displayln w)
   (displayln x)
   (displayln y)
   (displayln z))

Просто возвращает свой аргумент, означающий, что переписчик совпадений не нашел соответствия для этого шаблона.

Любой совет приветствуется.

Спасибо.

1 Ответ

0 голосов
/ 14 марта 2011

Я раньше не работал с макросами Scheme или функциями, связанными с синтаксисом, но из того, что я знаю о Scheme, то, что вы написали:

(λ ,<var> . ,<vars> . ,<expr> . ,<exprs>)

не имеет смысла, потому что ваша "пара" (котораясоздается с точками) на самом деле содержит 4 элемента.Вы хотели составить список?

...