方案模式匹配
我编写了以下语法规则:
(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”。我相信我的问题是我不理解符号 `
、.
和 ,
在模式匹配中的正确用法。
如果有人可以向我展示正确的方法,我将不胜感激。
谢谢。
I have written the following syntax rule:
(define-syntax match-rewriter
(syntax-rules ()
((_ (patt body) ...)
(λ (x) (match x (patt body) ... (_ x))))))
which is essentially match-lambda
except that it returns its argument if no match is found rather than throwing an exception.
Now I want to write a function, let_as_lambda
, that will take strings of source code as input and rewrite the let
statements as the new let_as_lambda
function. This is what I have:
(define let_as_lambda
(match-rewriter (`(let((,<var> ,<val>)) ... ,<expressions>)
`((lambda (,<var> ...) ,<expressions>) ,<val> ...))))
It is clearly wrong as:
(let_as_lambda '(let((x 3)) (+ x 2)))
returns:
'((λ ((x) ...) (+ x 2)) (3) ...)
still showing the ellipses and with the "3" in parentheses. I believe my problem is that I don't understand the proper usage of the symbols `
, .
, and ,
in pattern matching.
If someone could show me the correct way to do this it would be greatly appreciated.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可能会感到困惑,因为您使用两种不同的模式匹配工具。第一个是通过
syntax-rules
得到的,第二个是match
。它们看起来足够接近,但存在一些重要的差异 - 在这种情况下,主要问题是与syntax-rules
不同,您不能在准规则中使用...
引用匹配
的结果。因此,要处理匹配值的列表,您需要使用unquote-splicing
(或,@
)和其他函数,如map
等。例如,比较这两个表达式的结果:作为旁注,如果通常的准引用能够满足您的要求,那就太好了,但是对于完整的解决方案,它需要可以使用简单的函数也是如此——这使整个事情变得复杂(
...
的使用需要转换为apply
)。You're probably confused because you use two different pattern matching tools. The first is what you get with
syntax-rules
and the second ismatch
. They seem close enough but there are some important differences -- and in this case, the main problem is that unlikesyntax-rules
, you cannot use...
in quasi-quoted results of amatch
. So to deal with lists of matched values you need to useunquote-splicing
(or,@
) and other functions likemap
etc. For example, compare the results of these two expressions:As a side note, it would be nice if the usual
quasi-quote
would do what you want, but for a complete solution it needs to be possible with simple functions too -- and that complicates the whole thing (uses of...
will need to translate toapply
).