方案将 let* 重写为嵌套的一元 let [英] Scheme rewrite let* as nested unary lets

查看:41
本文介绍了方案将 let* 重写为嵌套的一元 let的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个函数 match-rewriter,它本质上是 match-lambda ,但如果没有找到匹配,它会返回它的参数:

I have written a function match-rewriter that is essentially match-lambda except that it returns its argument if no match is found:

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

现在我想使用 match-rewriter 来获取表示 let* 源代码的字符串,并将其重写为嵌套的一元 lets:

Now I would like to use match-rewriter to take strings representing source code for let* and rewrite it as nested unary lets:

(define let*→nested-unary-lets
  (match-rewriter (`(let*((,<var> ,<val>) ...) ,<expr1> ,<expr2> ...)

我真的很困惑如何进行模式匹配.我需要返回:

I am really stumped over how to pattern match this. I need to return:

`(let((,<var1> ,<val1>)) let((,<var2> ,<val2>)) let((...)) ... )...) ,<expr1> . ,@<expr2>)

但是嵌套让我难住了.任何建议表示赞赏.

But the nesting has me stumped. Any advice is appreciated.

好的,这是我最好的尝试:

Okay, here is my best attempt:

(define let*→nested-unary-lets
  (match-rewriter
   (`(let* (()) ,<expr1> ,<expr2> ...)
   (`(let () ,<expr1> . ,<expr2>)))
   (`(let* ((,<var1> ,<val1>) (,<var2> ,<val2>) ...) ,<expr1> ,<expr2> ...)
    `(let ((,<var1> ,<val1>) (let*→nested-unary-lets 
                               '(let* ((,<var2> ,<val2>) ...) ,<expr1> . ,<expr2>)))))
   ))

但这就是它的行为方式:

But this is how it behaves:

(let*→nested-unary-lets '(let* ((a 1) (b (+ a 1)) (c (+ a b))) (displayln c)))'(让 ((a 1)(let*→nested-unary-lets'(让* (((b c) ((+ a 1) (+ a b)))...)(displayln c))))))

(let*→nested-unary-lets '(let* ((a 1) (b (+ a 1)) (c (+ a b))) (displayln c))) '(let ((a 1) (let*→nested-unary-lets '(let* (((b c) ((+ a 1) (+ a b))) ...) (displayln c)))))

我对以下参数的顺序感到困惑:

I am confused about the order of the arguments in:

(let* (((b c) ((+ a 1) (+ a b)))

在我看来应该是:

(let* ((b (+ a 1)) (c (+ a b)))

此外,如果对 let*→nested-unary-lets 的调用能够执行而不只是打印为文本,那就太好了.

Also, it would be nice if the call to let*→nested-unary-lets would execute instead of just printing as text.

推荐答案

是的,你可以这样做;应该不会太难.具体来说,您在此处需要的关键思想是不要尝试一次处理整个列表.相反,您的模式应该将第一个绑定与其余的绑定分开,然后将一个 let 包裹在 递归调用 中,以使其*->nested-unary-lets.

Yes, you can do this; it shouldn't be too difficult. Specifically, the key idea you need here is not to try to handle the whole list at once. Instead, your patterns should separate the first binding from the rest, and then wrap one let around a recursive call to let*->nested-unary-lets.

如果你在制定这个时遇到问题,请告诉我.

Let me know if you have trouble formulating this.

这篇关于方案将 let* 重写为嵌套的一元 let的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆