方案模式匹配

时间:2011-02-24 03:42:12

标签: scheme design-patterns racket matching

我编写了以下语法规则:

(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”。我相信我的问题是我不理解模式匹配中符号`.,的正确用法。

如果有人能告诉我正确的方法,我们将非常感激。

感谢。

1 个答案:

答案 0 :(得分: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)。