【问题标题】:Force evaluation of recursive call in pattern match模式匹配中递归调用的强制评估
【发布时间】:2011-07-04 15:31:38
【问题描述】:

我正在使用 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 并且不需要进一步的评估。

谢谢。

【问题讨论】:

    标签: recursion scheme pattern-matching racket


    【解决方案1】:

    您已经在使用 quasiquoting 在递归情况下输出您的答案,所以只需在递归调用 let*-&gt;nested-unary-lets 之前添加一个逗号 (,)(就像 &lt;var&gt;&lt;val&gt; 之前的那些)所以它立即评估。准引号中的, 可以拼接到任何表达式的结果中,而不仅仅是变量。行:

    `(let ((,<var> ,<val>)) (let*→nested-unary-lets '(let* (,@<clauses>) ,<exprs>)))
    

    还有一些其他问题:为了使,@ 工作,内部let* 之前的' 必须是`。这是我建议的版本:

    `(let ((,<var> ,<val>)) ,(let*→nested-unary-lets `(let* ,<clauses> . ,<exprs>)))
    

    这需要将&lt;exprs&gt; 的匹配更改为. ,&lt;exprs&gt; 以允许多个。

    【讨论】:

    • 非常感谢!事实证明它需要是: ,(let*→nested-unary-lets `(let* (,@) ,)) - 但如果没有你的建议,我永远不会到达那里。 :-)
    • @Schemer:我在,&lt;exprs&gt; 之前添加了. 以允许多个;如果你只匹配一个,你也不应该在 quasiquoted 输出中包含 .
    猜你喜欢
    • 2020-05-20
    • 1970-01-01
    • 2017-12-15
    • 2015-09-12
    • 2011-03-03
    • 1970-01-01
    • 2019-11-01
    • 2020-07-12
    • 1970-01-01
    相关资源
    最近更新 更多