强制评估模式匹配中的递归调用

时间:2011-02-25 22:21:12

标签: recursion scheme pattern-matching racket

我使用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,无需进一步评估。

感谢。

1 个答案:

答案 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>以允许多个匹配。