2011-03-14 95 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>) ...)