Схема: синтаксис сопоставления с образцом

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

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

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

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

Спасибо.


Хорошо, вот полная, более интересная проблема.

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

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

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

реализовать позволяет как лямбда-вызовы, но вот как это работает:

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

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

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

Спасибо.


person Schemer    schedule 14.03.2011    source источник


Ответы (1)


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

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

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

person user541686    schedule 14.03.2011
comment
Ты прав. Проблема с . было решено путем перезаписи совпадения как (λ (,‹var› . ,‹vars›) (,‹expr› . ,‹exprs›)) - person Schemer; 14.03.2011