我编写了以下语法规则:
(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”。我相信我的问题是我不理解模式匹配中符号`
,.
和,
的正确用法。
如果有人能告诉我正确的方法,我们将非常感激。
感谢。
答案 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
)。