0

我编写了一个函数match-rewriter,它本质上是match-lambda如果找不到匹配项则返回其参数:

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

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

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

我真的很困惑如何匹配这个。我需要返回:

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

但是嵌套让我很难过。任何建议表示赞赏。


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

(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>)))))
   ))

但这就是它的行为方式:

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

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

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

在我看来应该是:

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

let*→nested-unary-lets此外,如果执行调用而不是仅打印为文本,那就太好了。

4

2 回答 2

2

这是一个类似let*insyntax-rules的伪代码的定义,您可以使用它来编写自己的版本:

(let* ((a b) (c d) ...) body ...) === (let ((a b)) (let* ((c d) ...) body ...))
(let* () body ...) === body

您应该能够将其转换为 using 的函数match或 using 的宏syntax-rules

于 2011-02-25T01:42:31.213 回答
2

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

让我知道如果你在制定这个方面有困难。

于 2011-02-25T01:44:15.443 回答