方案模式匹配

发布于 2024-10-19 02:55:30 字数 883 浏览 2 评论 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”。我相信我的问题是我不理解符号 `., 在模式匹配中的正确用法。

如果有人可以向我展示正确的方法,我将不胜感激。

谢谢。

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谁的新欢旧爱 2024-10-26 02:55:30

您可能会感到困惑,因为您使用两种不同的模式匹配工具。第一个是通过 syntax-rules 得到的,第二个是 match 。它们看起来足够接近,但存在一些重要的差异 - 在这种情况下,主要问题是与 syntax-rules 不同,您不能在准规则中使用 ...引用匹配的结果。因此,要处理匹配值的列表,您需要使用 unquote-splicing (或 ,@)和其他函数,如 map 等。例如,比较这两个表达式的结果:

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

作为旁注,如果通常的准引用能够满足您的要求,那就太好了,但是对于完整的解决方案,它需要可以使用简单的函数也是如此——这使整个事情变得复杂(...的使用需要转换为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 is match. They seem close enough but there are some important differences -- and in this case, the main problem is that unlike syntax-rules, you cannot use ... in quasi-quoted results of a match. So to deal with lists of matched values you need to use unquote-splicing (or ,@) and other functions like map etc. For example, compare the results of these two expressions:

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

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 to apply).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文