方案:模式匹配语法

时间:2011-03-14 06:57:57

标签: mapping scheme syntax-error racket

这是对之前帖子的修改。我正在重新发布它,因为我认为原来没有得到任何更多的观点,因为我已经接受了部分答案。

我编写了一个函数 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作为lambda调用,但这就是它的行为方式:

(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 :(得分:1)

这种模式:

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

没有做你想要的。特别是,它相当于:

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

我建议您使用常规match模式,而不是准模式,直到您更好地了解它们的工作方式。这种模式将是:

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