我使用match-lambda来根据更基本的函数重写某些函数。下面是一个示例,它接受表示let *调用的输入代码的字符串,并将它们作为转换为嵌套的一元let的字符串返回:
(define let*→nested-unary-lets
(match-lambda
(`(let* (()) ,<exprs>)
`(let () ,<exprs>))
(`(let* ((,<var> ,<val>)) ,<exprs>)
`(let ((,<var> ,<val>)) (let () ,<exprs>)))
(`(let* ((,<var> ,<val>) . ,<clauses>) ,<exprs>)
`(let ((,<var> ,<val>)) (let*→nested-unary-lets '(let* (,@<clauses>) ,<exprs>))))))
以下是调用let *→nested-unary-lets:
的示例(let*→nested-unary-lets '(let* ((a 1) (b (+ a 1)) (c (+ a b))) (displayln c)))
'(let ((a 1))
(let*→nested-unary-lets
'(let* ((b (+ a 1)) (c (+ a b)))
(displayln c))))
我想知道是否有办法强制评估递归调用let *→nested-unary-lets,以便输出字符串只包含嵌套的let和requries,无需进一步评估。
感谢。
答案 0 :(得分:1)
您已经使用quasiquoting在递归情况下输出答案,因此只需在递归调用,
之前添加逗号(let*->nested-unary-lets
)(如<var>
之前的那些<val>
)所以立即对其进行评估。 quasiquotes中的,
可以拼接任何表达式的结果,而不仅仅是变量。这一行:
`(let ((,<var> ,<val>)) (let*→nested-unary-lets '(let* (,@<clauses>) ,<exprs>)))
还有一些其他问题:为了,@
能够正常工作,内部'
之前的let*
需要`
。这是我建议的版本:
`(let ((,<var> ,<val>)) ,(let*→nested-unary-lets `(let* ,<clauses> . ,<exprs>)))
这要求将<exprs>
的匹配更改为. ,<exprs>
以允许多个匹配。