You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clojure使用kern库时many-till递归解析栈溢出如何解决?

解决Kern库many-till解析器栈溢出的方案

原库中many-till的递归实现属于非尾递归,每一步解析成功后需要等待后续递归调用返回,再将当前结果cons到结果列表头部,输入长度增长时栈帧会线性积累最终触发栈溢出。
可通过尾递归累加器的方案重写many-till,完全消除栈消耗:

(defn many-till [p end]
  (fn [initial-state]
    (loop [state initial-state
           acc []]
      (let [end-result (end state)]
        (if (ok? end-result)
          ;; 如需完全对齐原实现返回列表的行为,可改为 (ok (seq acc) state)
          (ok acc state)
          (let [p-result (p state)]
            (if (error? p-result)
              p-result
              (recur (rest-state p-result) (conj acc (value p-result))))))))))

修改说明

  • 新增内部loop循环,使用两个状态变量:当前解析状态state、已解析结果累加器acc
  • 所有递归调用替换为尾位置的recur,复用栈帧,不会随输入长度增长产生新的栈帧
  • 解析结果直接追加到向量累加器中,无需等待后续调用返回,结束时直接返回累加结果,和原实现的返回值顺序完全一致,通用序列操作完全兼容

你现有业务代码无需修改,替换原many-till定义后即可支持任意长度的输入,不会触发栈溢出。

内容的提问来源于stack exchange,提问作者Unsatisfied Zebra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 01:15:03