为什么scala不进行尾调用优化?

2023-12-22

只是玩延续。目标是创建将接收另一个函数作为参数和执行量的函数,并返回将应用参数给定次数的函数。

实现看起来很明显

def n_times[T](func:T=>T,count:Int):T=>T = {
  @tailrec
  def n_times_cont(cnt:Int, continuation:T=>T):T=>T= cnt match {
        case _ if cnt < 1 => throw new IllegalArgumentException(s"count was wrong $count")
        case 1 => continuation
        case _ => n_times_cont(cnt-1,i=>continuation(func(i)))
      }
  n_times_cont(count, func)
}

def inc (x:Int) = x+1

    val res1 = n_times(inc,1000)(1)  // Works OK, returns 1001

val res = n_times(inc,10000000)(1) // FAILS

但没有问题 - 这段代码失败并出现 StackOverflow 错误。为什么这里没有尾部调用优化?

我使用 Scala 插件在 Eclipse 中运行它,它返回 线程“main”中的异常 java.lang.StackOverflowError 在 scala.runtime.BoxesRunTime.boxToInteger(来源未知) 在 Task_Mult$$anonfun$1.apply(Task_Mult.scala:25) 在 Task_Mult$$anonfun$n_times_cont$1$1.apply(Task_Mult.scala:18)

p.s.

F# 代码几乎是直接翻译,运行没有任何问题

let n_times_cnt func count = 
    let rec n_times_impl count' continuation = 
        match count' with
        | _ when count'<1 -> failwith "wrong count"
        | 1 -> continuation
        | _ -> n_times_impl (count'-1) (func >> continuation) 
    n_times_impl count func

let inc x = x+1
let res = (n_times_cnt inc 10000000) 1

printfn "%o" res

Scala 标准库has蹦床的实现scala.util.control.TailCalls。因此,重新审视您的实现...当您使用以下命令构建嵌套调用时continuation(func(t)),这些是尾调用,只是编译器没有优化。那么,让我们建立一个T => TailRec[T],其中堆栈帧将替换为堆中的对象。然后返回一个函数,该函数将接受参数并将其传递给该蹦床函数:

import util.control.TailCalls._
def n_times_trampolined[T](func: T => T, count: Int): T => T = {
  @annotation.tailrec
  def n_times_cont(cnt: Int, continuation: T => TailRec[T]): T => TailRec[T] = cnt match {
    case _ if cnt < 1 => throw new IllegalArgumentException(s"count was wrong $count")
    case 1 => continuation
    case _ => n_times_cont(cnt - 1, t => tailcall(continuation(func(t))))
  }
  val lifted : T => TailRec[T] = t => done(func(t))
  t => n_times_cont(count, lifted)(t).result
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么scala不进行尾调用优化? 的相关文章

  • 如何在 AWS S3 中保存和使用 Spark History Server 日志

    我想在AWS S3中记录和查看Spark历史服务器的事件日志 以下是spark defaults conf中记录的属性 spark hadoop fs s3a impl org apache hadoop fs s3a S3AFileSys
  • 我在 Scala 中将资源放在哪里?

    在学习使用 Scala 和 JavaFX 时 我在 a 中遇到了以下代码ProScalaFX 示例 https github com jpsacha ProScalaFX val resource getClass getResource
  • 副作用是纯函数中找不到的一切吗?

    可以肯定地说 以下二分法成立 每个给定的函数是 要么纯粹 或有副作用 如果是这样 函数的 副作用就是纯函数中找不到的任何东西 这很大程度上取决于您选择的定义 可以公平地说 函数是pure or impure 纯函数始终返回相同的结果并且不会
  • 将 Scala 文件转换为 Dll

    我有一些使用 IntelliJ 和 SBT Plugin 编写的 scala 代码 并希望将代码作为 C 的 DLL 提供给我 我已经尝试使用 ikvmc 我通过 package 将所有类打包在一个罐子中 之后 我手动设置一个 jar 其中
  • Scala中如何将DataFrame转换为RDD?

    有人可以分享一下如何转换dataframe to an RDD Simply val rows RDD Row df rdd
  • 写入 Delta 表时检测到架构不匹配 - Azure Databricks

    我尝试将 small radio json json 加载到 Delta Lake 表 在此代码之后我将创建表 我尝试创建 Delta 表 但收到错误 写入 Delta 表时检测到架构不匹配 可能与分区有关events write form
  • Scala 2.10、Double.isNaN 和拳击

    在 Scala 2 10 中 是someDouble isNaN预计装箱 运行我的代码调用 isNaN通过反编译器 我仍然看到对double2Double在我的代码中 鉴于新的AnyVal在 2 10 中工作 我希望它不会比java lan
  • 将无形状 HList 转换为 TupleN,其中元组形状不需要与 HList 形状完全匹配

    我想创建相当于 def toTupleN A1 AN L lt HList l L TupleN A1 AN 代码使用toTupleN仅当恰好有一个时才应该编译N中的值的组合l可以从中创建元组 其他任何内容都应该生成编译时错误 应考虑可用的
  • IntelliJ IDEA Scala 插件问题

    我对新的 Intellij IDEA 10 和 Scala 插件有疑问 当我在 Scala 源文件中输入任何内容时 编辑器会永久冻结 在其他文件 java 和其他 编辑器中效果很好 结构视图 scala 检查和显示成员功能已关闭 堆大小增加
  • Scala:在运行时获取 mixin 接口

    我需要在运行时从给定的类获取所有接口 全部加载在类加载器中 例如 如果一个类是这样声明的 trait B trait C trait D class A extends B with C with D 我想在运行时获取这些信息 A 取决于
  • 哪些 ORM 与 Scala 配合得很好? [关闭]

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

    简洁版本 我怎样才能创建一个Promise
  • Scala 集合不一致

    为什么 Scala Collections API 中的集合和列表之间缺乏一致性 例如 有不可变的 Set 但也有可变的 Set 如果我想使用后者 我可以简单地这样做 val set Set A set new A 但是 本身不存在可变列表
  • Scala 相当于 Java 的 Number

    我正在尝试为数值域类型构建类型层次结构 例如AYear is an Int 这是一个Number a Percentage is a Double 这是一个Number等等 我需要层次结构以便我可以调用toInt or toDouble关于
  • 最小重复子串

    我正在看 Perl代码高尔夫页面 http www perlmonks org node id 82878 不要问为什么 并遇到了这个 第 3 洞 最小重复图案 编写一个子例程 它接受一个字符串 该字符串可能包含 重复模式 并返回最小的重复
  • 阶乘的 Scala 排列

    我怎样才能找到n Scala 中某些字母的排列 Scala 2 9 RC1 scala gt abc permutations toList res58 List String List abc acb bac bca cab cba
  • Source.getLines 中的默认参数错误 (Scala 2.8.0 RC1)

    假设我运行 Scala 2 8 0 RC1 以下 scala 代码应该打印出文件 c hello txt 的内容 for line lt Source fromPath c hello txt getLines println line 但
  • Scala:如何在超类上实现克隆方法,并在子类中使用它?

    我可能会以错误的方式处理这个问题 但我想要一个像这样的对象 class MyDataStructure def myClone val clone new MyDataStructure do stuff to make clone the
  • 对 Scala Not Null 特征的库支持

    Notice 从 Scala 2 11 开始 NotNull已弃用 据我了解 如果您希望引用类型不可为空 则必须混合魔法NotNull特征 编译器会自动阻止你输入null 可以值在里面 看到这个邮件列表线程 http www nabble
  • 类型级编程有哪些示例? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我不明白 类型级编程 是什么意思 也无法使用Google找到合适的解释 有人可以提供一个演示类型级编程的示例吗 范式的解释和 或定义将

随机推荐

  • Mysql排除记录

    我有两张表 用户和角色 一个用户可以拥有多个角色 user ID FIRSTNAME LASTNAME etc 1 PETER Blomp role ID ROLEID USERID which is user ID 70 5 1 pete
  • 如何通过CORS传递cookie?

    我有一个项目 使用 Axios 从客户端发送 HTTP 请求 axios create baseURL http localhost 8081 withCredentials true 我想这允许 cookie 我确信它会在您提出请求之前显
  • 如何使用 OLEDB 从 Excel 文件(2007 格式)读取超过 256 列

    我正在尝试使用 C 中的 OLEDB 导入包含超过 256 列的 Excel 文件 我尝试了各种方法 但似乎不可能从 Excel 2007 格式 文件中读取超过 256 列 我想知道这是一个错误还是我只是错过了一些东西 这是我使用的连接字符
  • 在没有子查询的 MySQL 中,ORDER BY 优先于 GROUP BY

    我有以下查询 它可以完成我想要的操作 但我怀疑可以在没有子查询的情况下执行此操作 SELECT FROM SELECT FROM versions ORDER BY ID DESC AS X GROUP BY program 我需要的是按程
  • 子类化 UILabel

    我在同一个网站上阅读了如何插入和 UILabel 子类 UILabel 并覆盖所需的方法 在将其添加到我的应用程序之前 我决定在独立的测试应用程序中对其进行测试 代码如下所示 这是 MyUILabel h import
  • 仅获取所有父级 WooCommerce 类别

    我正在尝试获取 WooCommerce 的所有父类别 而不是子类别 terms get terms taxonomy gt product cat hide empty gt false parent gt 0 但它不起作用 如何仅获取父类
  • 如何根据列的顺序添加自增主键?

    我需要将自动增量 id 添加到已有的表中 我做了 ALTER TABLE table name ADD column name INT NOT NULL AUTO INCREMENT FIRST ADD PRIMARY KEY column
  • 取消选择 RowDetailsTemplate 后调整数据网格高度

    我正在使用 RowDetailsTemplate 显示行的嵌套数据网格 现在 当我选择一行来显示此嵌套数据网格时 数据网格的高度会扩展 但当取消选择该行时 它不会减少其高度 有没有办法在行详细信息折叠后将数据网格大小调整为其原始高度 是否可
  • 多对多关系的复选框

    class PlayerProfile lt ActiveRecord Base has many playing roles has many player roles through playing roles accepts nest
  • Magento 1.6.2 无法重新索引产品平面数据

    我们的 magento 1 6 2 无法重新索引产品平面数据 有时它还会显示 重新索引过程存在问题 我根据其他用户的经验尝试了很多解决方案 没有结果 我们进口了散装产品 但我们不确定这是重新索引问题的原因 理想的解决方案是什么 这是我在 s
  • 在版权符号之前插入特殊字符“”

    我们的源代码在每个 CSS 文件的顶部都包含版权 版权所有 每次 Firefox 样式编辑器加载 CSS 文件时 都会在版权符号之前插入一个特殊字符 版权所有 每次加载文件时它都会添加一个额外的特殊字符 我不认为这仅限于 Firefox 但
  • 将位图传递给在 logcat 上获取消息的其他活动 FAILED BINDER TRANSACTION

    当我将位图图像传递给其他活动时 我在 logcat 上收到 mag 03 20 12 06 56 553 E JavaBinder 280 FAILED BINDER TRANSACTION 它发生在大尺寸图像上 小尺寸图像运行良好 我该怎
  • 尝试使用实体框架保存大型 xml 时出现“ORA-00932:不一致的数据类型:预期的 NUMBER 获得 NCLOB”错误

    当我尝试使用 ADO NET 实体框架将具有大型 xml 的新记录插入具有 XmlType 列的 oracle 表时 出现以下错误 Oracle DataAccess Client OracleException Message ORA 0
  • 展开 pandas 数据框列中字典的嵌套列表

    我有一个名为 leads 的数据帧 是通过将 SFDC SOQL 的输出保存到数据帧中而得到的 我一直在尝试扩展 Leads r record 列 Company Month Amount Leads r done Leads r reco
  • 使用 ZeroMQ 的 C++ RPC 框架

    我需要使用 ZeroMQ 推拉套接字模式用 C 编写客户端 服务器应用程序 客户端必须对服务器接口中指定的函数进行 RPC 调用 我想知道是否有一个开源且商业可用的库 框架主要用于此目的 主要是 C 我做了一些谷歌搜索 似乎有一些用 pyt
  • Chrome 浏览器 - navigator.language 不返回国家/地区代码

    自最近几个月以来 我在从 window navigator language 检测 CountryCode 时遇到问题 我当前在 Chrome 上的语言是法语 瑞士 目前它仅返回语言 window navigator language fr
  • 通过列索引而不是列名称调用数据框中的列 - pandas

    如何使用数据框中的索引而不是名称来调用代码中的列 例如我有数据框df有柱子a b c 而不是打电话df a 我可以使用它的列索引来调用它吗df 1 您可以使用iloc http pandas pydata org pandas docs v
  • 即使使用代理,Nodejs 也不会为 React CRA 应用程序设置 cookie

    我有一个nodejs express React CRA 应用程序 我正在尝试从nodejs 设置一个cookie 服务器位于端口 4001 因此在我的 React 应用程序的 project json 中我有 proxy http loc
  • 如何制作操作系统启动时启动的启动程序

    假设我有一个 C 程序可以执行某些操作 我希望该程序继续自行运行或在计算机启动时自动开始执行 我怎样才能使这个程序不可检测 即它不能在任务管理器的进程列表中被检测到 假设我有一个在 Windows 窗体上显示随机数的程序 for Rando
  • 为什么scala不进行尾调用优化?

    只是玩延续 目标是创建将接收另一个函数作为参数和执行量的函数 并返回将应用参数给定次数的函数 实现看起来很明显 def n times T func T gt T count Int T gt T tailrec def n times c