是否存在无法使用尾递归编写的问题?

2024-02-02

尾递归是函数式语言中重要的性能优化策略,因为它允许递归调用消耗常量堆栈(而不是 O(n))。

是否存在根本无法用尾递归风格编写的问题,或者是否总是可以将朴素递归函数转换为尾递归函数?

如果是这样,有一天函数式编译器和解释器是否会足够智能来自动执行转换?


是的,其实你can获取一些代码并将每个函数调用(以及每个返回)转换为尾调用。你最终得到的就是所谓的延续传递风格,或 CPS。

例如,这是一个包含两个递归调用的函数:

(define (count-tree t)
  (if (pair? t)
    (+ (count-tree (car t)) (count-tree (cdr t)))
    1))

如果将此函数转换为连续传递样式,它将如下所示:

(define (count-tree-cps t ctn)
  (if (pair? t)
    (count-tree-cps (car t)
                    (lambda (L) (count-tree-cps (cdr t)
                                                (lambda (R) (ctn (+ L R))))))
    (ctn 1)))

额外的参数,ctn, 是一个过程count-tree-cps尾部调用而不是返回。 (sdcvvc 的答案说你不能在 O(1) 空间中完成所有事情,这是正确的;这里每个延续都是一个占用一些内存的闭包。)

我没有将调用转换为car or cdr or +进入尾部调用。这也可以做到,但我认为这些叶子调用实际上是内联的。

现在是有趣的部分。鸡计划 http://www.call-with-current-continuation.org/实际上对它编译的所有代码都进行了这种转换。鸡编的程序永远不会回来。有一篇经典论文解释了 Chicken Scheme 这样做的原因,该论文写于 1994 年 Chicken 实施之前:反对者不应该反对其论点,第二部分:切尼关于 M.T.A. http://home.pipeline.com/~hbaker1/CheneyMTA.html

令人惊讶的是,连续传递风格在 JavaScript 中相当常见。你可以使用它进行长时间运行的计算 http://marijn.haverbeke.nl/cps/,避免浏览器的“慢脚本”弹出窗口。它对于异步 API 很有吸引力。jQuery.get http://www.webmonkey.com/tutorial/Easy_XML_Consumption_using_jQuery?oldid=20032(XMLHttpRequest 的简单包装)显然采用连续传递风格;最后一个参数是一个函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否存在无法使用尾递归编写的问题? 的相关文章

  • 如何在 Perl 中以函数式风格进行编码?

    你如何 have a sub返回一个sub or 将文本作为代码执行 in Perl 另外 如何拥有匿名函数存储状态 子返回子作为coderef example 1 return a sub that is defined inline s
  • OCaml 作为 C 库,hello world 示例

    我希望通过 C 调用 OCaml 代码 方法是将 OCaml 编译为包含 C 接口的静态或共享库 这一页 https caml inria fr pub docs manual ocaml intfc html似乎解释了如何为 OCaml
  • “函数是第一等值”这到底是什么意思?

    有人可以用一些很好的例子清楚地解释它吗 在解释函数式编程时 我在 Scala 中遇到了这句话 一流 并不是一个正式定义的概念 但它通常意味着一个实体具有三个属性 有可能used 不受限制 只要 普通 值可以 即从函数传递和返回 放入容器等
  • Java中的递归排列生成错误结果

    问题是生成字典排列 起初 我的代码是这样的 public class Problem24 public static void main String args permutation 123 public static void perm
  • 是否可以只迭代一个流一次并执行 2 个或更多操作?

    给定代码 List
  • MySQL 最佳实践:SELECT 子递归尽可能提高性能?

    我想选择一个根项目及其子项 使其性能尽可能高 我更喜欢使用嵌套集模型 但这次表结构遵循邻接模型 有关嵌套集和邻接模型的更多信息 http mikehillyer com articles managing hierarchical data
  • 这个对自身单位的列表理解是如何工作的?

    在 haskell IRC 频道中有人问 是否有一种简洁的方法来定义一个列表 其中第 n 个条目是之前所有条目的平方和 我认为这听起来像一个有趣的谜题 递归定义无限列表是我真正需要练习的事情之一 所以我启动了 GHCi 并开始尝试递归定义
  • 正确使用术语 Monoid

    从下面的例子来看 我认为这样的说法是正确的String在串联运算下定义了一个幺半群 因为它是关联二元运算 并且String碰巧有一个身份元素 它是一个空字符串 scala gt Jane Doe Jane Doe res0 Boolean
  • 在管道中重用变量的功能方式

    在 javascript 和 typescript 中与 Ramda 一起使用函数式编程 我经常发现自己编写如下代码 const myFun c gt const myId c id const value pipe getAnotherO
  • 为什么Racket中foldl的定义方式很奇怪?

    在 Haskell 中 与许多其他函数式语言一样 函数foldl被定义为 例如 foldl 0 1 2 3 4 10 这没关系 因为foldl 0 1 2 3 4 根据定义 0 1 2 3 4 但是 在 球拍 中 foldl 0 1 2 3
  • Javascript - deepEqual 比较

    问题 来自 Eloquent Javascript 第二版 第 4 章 练习 4 编写一个函数 deepEqual 它接受两个值 并且仅当它们相等时才返回 true 是相同的值或具有相同属性的对象 其值也是 与对 deepEqual 的递归
  • 我在函数的最后一次递归调用中得到“方案应用程序而不是过程”

    所以这是代码 define time prime test n newline display n start prime test n runtime define start prime test n start time if pri
  • @tailrec为什么这个方法不编译为“包含不在尾部位置的递归调用”?

    tailrec private def loop V key String V key match case gt loop key 此方法无法编译并抱怨它 包含不在尾部位置的递归调用 有人可以向我解释一下发生了什么事吗 这个错误消息对我来
  • 合并xml文档

    我遇到的所有关于合并 XML 文档的解决方案都无法实现我的愿望 让我解释 XML 文档 1 a b title Original Section b title Original Child Section b b title Origin
  • 如何在 javascript 正则表达式中匹配平衡分隔符?

    我原以为这个问题是不可能的 据我所知 Javascript 的正则表达式既没有递归插值 也没有漂亮的 NET 平衡组功能 但问题就在那里 如问题 12 所示正则表达式 alf nu http regex alf nu 匹配平衡对 lt an
  • PHP递归遍历对象树[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • php递归合并

    我需要以某种不同的方式合并一些数组 我使用 array merge recursive 然而 有一些事情我需要改变 但我不知道如何改变 这是来自 php net 的引用 但是 如果数组具有相同的数字键 则后面的值 不会覆盖原始值 但会追加
  • 卷积函数可以写成尾递归形式吗?

    我有一个函数 我想以尾递归形式编写 该函数计算求和的方法数k通过滚动s双面模具n次 我已经在上面看到了这个函数的数学解这个答案 https math stackexchange com questions 397689 why convol
  • 如何使用递归查找数字中的最小元素 [C]

    好的 所以我正在准备我的 C 考试 当谈到递归时我有点卡住了我是大学一年级的学生 这对我来说似乎有点困难 练习要求在给定的数字中使用递归函数我需要找到最小的元素 例如 52873 是 2 程序需要打印 2 include
  • 在 Pari-GP 中嵌套特定递归

    每个人 我最初在 Stackexchange 上发布了类似的问题 它已移至此处 可以在链接中找到 在 Matlab 中声明函数递归序列 https stackoverflow com questions 67146061 declaring

随机推荐

  • 为什么串联的 RequireJS AMD 模块需要加载程序?

    我们在开发过程中喜欢 RequireJS 和 AMD 在这里我们可以编辑模块 在浏览器中点击重新加载 然后立即看到结果 但是 当需要将我们的模块连接到单个文件以进行生产部署时 显然必须有一个 AMD 加载器仍然存在 无论该加载器是 Requ
  • Python:查找字符串中的单词

    我想在字符串中找到这个单词 如下所示 kkk I do not like that car if like in kkk print like elif dislike in kkk print dislike elif hate in k
  • Laravel 忽略变异器

    我正在使用 Laravel 的 Mutator 功能 并且我有以下 Mutator public function setFirstNameAttribute value this gt attributes first name strt
  • systemctl 状态显示 inactive dead

    我正在尝试编写自己的 简单 systemd 服务 该服务执行一些简单的操作 例如使用 shell 脚本将数字 1 到 10 写入文件 我的服务文件如下所示 Unit Description NandaGopal Documentation
  • 如何在我的类中实现前置和后置自增/自减运算符?

    我想要超载 运算符在我的 c 类中使用运算符重载来使用预增量和后增量 但只有后增量才有效 如何使这两个功能在我的班级中起作用 假设我做了一个 ABC 类 比如 using System using System Collections Ge
  • 设置变换后图像的宽度和高度:旋转

    i have a div with width 190px and height 260px i assign img tag on that div when i upload an image that shows how the im
  • cmd编程中的速度和时间问题

    最近存在一个问题 即如何将具有用户预定义文件类型扩展名的许多文件从一个文件夹移动到许多不同的文件夹 这些文件夹是根据文件名中的密钥字符串 年份 立即创建的 此外 当移动到新创建的文件夹时 文件应在没有用户预定义文件类型扩展名的情况下保存 文
  • 指针变量只是带有一些运算符的整数还是“符号”?

    编辑 最初的单词选择令人困惑 象征性 这个词比原来的 神秘的 要好得多 在关于我之前的 C 问题的讨论中 我被告知指针是 类似于整数的简单值类型 https stackoverflow com questions 32043314 over
  • python asyncio aiohttp 超时

    注意事项 这是我第一次使用 asyncio 所以我可能做了一些非常愚蠢的事情 场景如下 我需要 http ping 一个巨大的 url 列表来检查它们是否响应 200 或任何其他值 尽管像 gobuster report 200 403 等
  • 如何使用重构从类中删除泛型类型

    我有这门课 public class TimeIntCo
  • 搜索多个字符串

    我知道在文件 kmp 中查找一个字符串或在文件 trie 中查找各种字符串的有效方法 但是 多年来 我一直想知道是否有一种方法 有时认为不可能 在多个文件中搜索多个字符串 假设我有一百万个文件 我想回答诸如 查找包含字符串 香蕉 摩托艇 和
  • Pyspark结构化流Kafka配置错误

    我之前已经成功地将 pyspark 用于 Spark Streaming Spark 2 0 2 和 Kafka 0 10 1 0 但我的目的更适合结构化流 我尝试使用在线示例 https spark apache org docs 2 1
  • 微服务横向扩展数据库的最佳实践或设计

    微服务的主要好处是可以通过使用多个容器实例和负载平衡来扩展一种服务 类型 以提高吞吐量 但有一件事是 服务类型 的多个实例 即容器 共享同一个数据库实例 当多个实例在该数据库实例上写入 读取时 这可能会造成性能瓶颈 传统上 我们会扩展该数据
  • 使用 css 显示/隐藏 html 表格列

    我想显示一个基本的 html 表 其中包含用于切换显示 隐藏附加列的控件 table tr th Column 1 th th class col1 1a th th class col1 1b th th Column 2 th th c
  • Yii:HAS_MANY 搜索

    我有以下表格 user id cv personal data id cv personal data id firstname surname gender address cv laboral exp id user id positi
  • 启动时出现空白页

    在获得启动画面之前 当我启动应用程序时 我会看到一段时间的空白页 Activity但我还是明白了 怎么了 清单文件
  • Express JS 4.0 命令行工具不起作用

    我使用express 3 x有一段时间了 命令行工具运行得非常好 我决定更新到 4 0 以便我可以尝试一下并使旧应用程序兼容 4 x sudo npm install g express 安装快递完全没问题 但是当我尝试时 exprsss
  • Python多处理调用对象方法[重复]

    这个问题在这里已经有答案了 我想使用Python的多处理模块来启动一个新进程 该进程创建一些其他对象并调用该对象的loops forever方法 在我的主课中 我有 import OtherService from multiprocess
  • GWT 中的 JOptionPane.showInputDialog()

    是否有任何简单的方法来创建具有单个文本输入控件的模态对话框实例 该实例将在按 确定 时返回输入到文本控件中的字符串 我正在寻找类似于 Swing 中的 JOptionPane showInputDialog 一行的东西 您可以创建自己的类
  • 是否存在无法使用尾递归编写的问题?

    尾递归是函数式语言中重要的性能优化策略 因为它允许递归调用消耗常量堆栈 而不是 O n 是否存在根本无法用尾递归风格编写的问题 或者是否总是可以将朴素递归函数转换为尾递归函数 如果是这样 有一天函数式编译器和解释器是否会足够智能来自动执行转