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

Это редактирование предыдущего поста. Я отправляю репост, потому что думаю, что у оригинала больше нет просмотров, так как я уже принял частичный ответ.

Я написал функцию 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 Ответ

1 голос
/ 17 марта 2011

Этот шаблон:

((,<var> ,<val>) . (,<vars> ,<vals>))

не делает то, что вы хотите.В частности, это эквивалентно:

((,<var> ,<val>) ,<vars> ,<vals>)

Я рекомендую использовать обычные match шаблоны, а не квази-шаблоны, пока вы не поймете, как они работают.Шаблон для этого будет:

(list (list <var> <val>) (list <vars> <vals>) ...)
...