2011-03-14 97 views
0

这是对先前文章的编辑。我正在转发它,因为我认为原文没有得到更多的意见,因为我已经接受了部分答案。方案:模式匹配语法

我已经写了一个函数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>)))) 

实现让为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

这种模式:

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

不会做你想做的。特别是,它等同于:

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

我推荐你使用普通match模式,而不是准的模式,直到你有他们的工作更好的感觉。这种模式将是:

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