这是对先前帖子的编辑。我之所以重新发布,是因为我已经收到了部分答案,因此我认为原版将不再获得任何意见。
我写了一个函数 match-rewriter ,它只是match-lambda,除了如果找不到匹配项,它会返回其参数。
使用匹配重写器,我希望能够编写可以传递给另一个函数的规则 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>))))
以lambda调用的形式实现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))
只返回其参数,这意味着match-rewriter找不到此模式的匹配项。
任何建议表示赞赏。
谢谢。
最佳答案
此模式:
((,<var> ,<val>) . (,<vars> ,<vals>))
不做你想要的。特别是,它等效于:
((,<var> ,<val>) ,<vars> ,<vals>)
我建议您使用常规的
match
模式,而不是准模式,直到您对它们的工作方式有了更好的了解。此模式为:(list (list <var> <val>) (list <vars> <vals>) ...)
关于mapping - 方案: pattern matching syntax,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5295641/