Это редактирование предыдущего поста. Я отправляю репост, потому что думаю, что у оригинала больше нет просмотров, так как я уже принял частичный ответ.
Я написал функцию 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))
Просто возвращает свой аргумент, означающий, что переписчик совпадений не нашел соответствия для этого шаблона.
Любой совет приветствуется.
Спасибо.