2011-02-24 101 views
0

我寫了下面的語法規則:方案模式匹配

(define-syntax match-rewriter 
    (syntax-rules() 
    ((_ (patt body) ...) 
    (λ (x) (match x (patt body) ... (_ x)))))) 

,如果沒有發現匹配,而不是拋出異常基本上是match-lambda只不過它返回它的參數。

現在我想寫一個函數let_as_lambda,它將採用一串源代碼作爲輸入並將let語句重寫爲新的let_as_lambda函數。這是我有:

(define let_as_lambda 
    (match-rewriter (`(let((,<var> ,<val>)) ... ,<expressions>) 
        `((lambda (,<var> ...) ,<expressions>) ,<val> ...)))) 

,這顯然是錯誤的,因爲:

(let_as_lambda '(let((x 3)) (+ x 2))) 

回報:

'((λ ((x) ...) (+ x 2)) (3) ...) 

仍呈現橢圓,並在括號中的 「3」。我相信我的問題是我不瞭解模式匹配中符號`.,的正確用法。

如果有人能告訴我正確的方法來做到這一點,將不勝感激。

謝謝。

回答

2

您可能會感到困惑,因爲您使用了兩種不同的模式匹配工具。第一種是你用syntax-rules得到的結果,第二種是match。它們似乎足夠接近但存在一些重要差異 - 在這種情況下,主要問題是與syntax-rules不同,您不能在match的準引用結果中使用...。所以對付你需要使用unquote-splicing(或,@)匹配的值和其他功能,如map等。例如列表,比較這兩個表達式的結果:

(match '(1 2 3) [`(,x ...) `(foo ,x ...)]) 
(match '(1 2 3) [`(,x ...) `(foo ,@x)]) 

作爲一個側面說明,這將是如果通常的quasi-quote可以做你想做的事情,那就很好,但是對於一個完整的解決方案,它也需要使用簡單的功能 - 這使整個事情變得複雜(使用...需要翻譯成apply)。

+0

當!我正在寫我的。 Eli,你太快了。你對關於將quasiquote加上「......」的可行性的評論會使你比我的更好。正如我的學生寫的:> O – 2011-02-24 05:39:58

+0

啊,謝謝,「@」讓世界變得不同。 :-) – Schemer 2011-02-24 06:00:00