使用 Scala 延续实现收益(收益回报)

2023-12-29

如何实现 C#yield return使用 Scala 延续?我希望能够编写 ScalaIterator风格相同。评论里有刺这篇 Scala 新闻文章 http://www.scala-lang.org/node/2096,但它不起作用(尝试使用 Scala 2.8.0 beta)。答案在一个相关问题 https://stackoverflow.com/questions/1655738/does-scala-have-an-equivalent-to-c-yield建议这是可能的,但是尽管我已经使用分隔延续一段时间了,但我似乎无法完全理解如何做到这一点。


在引入延续之前,我们需要构建一些基础设施。 下面是一个蹦床 http://blog.richdougherty.com/2009/04/tail-calls-tailrec-and-trampolines.html运行于Iteration对象。 迭代是一种计算,可以Yield一个新的值或者它可以是Done.

sealed trait Iteration[+R]
case class Yield[+R](result: R, next: () => Iteration[R]) extends Iteration[R]
case object Done extends Iteration[Nothing]

def trampoline[R](body: => Iteration[R]): Iterator[R] = {
  def loop(thunk: () => Iteration[R]): Stream[R] = {
    thunk.apply match {
      case Yield(result, next) => Stream.cons(result, loop(next))
      case Done => Stream.empty
    }
  }
  loop(() => body).iterator
}

蹦床使用一个内部循环来转动序列Iteration物体变成Stream。 然后我们得到一个Iterator通过致电iterator在生成的流对象上。 通过使用Stream我们的评价是懒惰的;在需要之前我们不会评估下一次迭代。

蹦床可以用来直接构建迭代器。

val itr1 = trampoline {
  Yield(1, () => Yield(2, () => Yield(3, () => Done)))
}

for (i <- itr1) { println(i) }

这写起来非常可怕,所以让我们使用分隔延续来创建我们的Iteration自动对象。

我们使用shift and reset运算符将计算分解为Iterations, 然后使用trampoline转动Iteration变成一个Iterator.

import scala.continuations._
import scala.continuations.ControlContext.{shift,reset}

def iterator[R](body: => Unit @cps[Iteration[R],Iteration[R]]): Iterator[R] =
  trampoline {
    reset[Iteration[R],Iteration[R]] { body ; Done }
  }

def yld[R](result: R): Unit @cps[Iteration[R],Iteration[R]] =
  shift((k: Unit => Iteration[R]) => Yield(result, () => k(())))

现在我们可以重写我们的示例。

val itr2 = iterator[Int] {
  yld(1)
  yld(2)
  yld(3)
}

for (i <- itr2) { println(i) }

好多了!

现在这是一个来自C# 参考页 http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx for yield这显示了一些更高级的用法。 这些类型可能有点难以适应,但是一切都有效。

def power(number: Int, exponent: Int): Iterator[Int] = iterator[Int] {
  def loop(result: Int, counter: Int): Unit @cps[Iteration[Int],Iteration[Int]] = {
    if (counter < exponent) {
      yld(result)
      loop(result * number, counter + 1)
    }
  }
  loop(number, 0)
}

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

使用 Scala 延续实现收益(收益回报) 的相关文章

随机推荐

  • Android:如何在应用程序启动时执行用户手册或应用程序说明

    我是 Android 开发新手 我需要在应用程序启动时显示像 Flip kart 应用程序这样的用户手册 请参考下图 您将会了解 我实际上想要实现什么 有没有任何标准方法可以实现这一目标 您可以手动完成所有工作 或者使用名为 Showcas
  • RStudio 中使用列表自动完成代码

    鉴于以下列表 我是否需要在更清晰的代码或自动完成之间进行选择 或者我可以两者兼得吗 我在 MacOS 10 10 5 上使用最新版本的 RStudio gt l lt list gt l a lt data frame ID stringi
  • 如何在可变参数包中找到“min”类型?

    min 类型是指比较的类型less比所有根据编译时函数 例如sizeof 我有一个实施草案 http ideone com eXLkrM 先介绍一下我面临的两个问题 include
  • VS Code 不断以带有 BOM 的 UTF-8 格式保存我的文件

    VS Code 不断以带有 BOM 的 UTF 8 格式保存我的文件 我的files encoding未设置设置 默认为utf8 在我的用户设置或工作区设置中 files autoGuessEncoding设置也未设置 默认为false 当
  • 有没有办法为 2 个具有不同包名称的应用程序提供 1 个 Firebase 数据库?

    我有 2 个应用程序 不同的包名称 适合 2 个不同的用户组 一个将数据放入数据库 另一个检索数据 因此 我只需要 1 个 firebase 数据库用于这两个应用程序 据我所知 Firebase 只允许 1 个数据库对应 1 个包名称 有没
  • NUnit 3.0 TestCase const 自定义对象参数

    我已经写好了课程SomeObject我想定义一个const要在我的中保留 重用的该对象的实例TestCases 我应该如何重写下面的代码来实现这种行为 TestFixture public class SomeObjectTests pri
  • Python:按任意列对文件进行排序,其中列包含时间值

    我有一个人的 txt 文件 每个人旁边都有两次 这是 txt 文件 Xantippe 09 00 11 00 Erica 10 00 12 06 Marcia 09 30 11 45 Elizabeth 10 15 12 10 Angela
  • 使用 AWS Java SDK v2 从 AWS EKS 获取身份验证令牌

    如何使用 AWS Java SDK v2 从 AWS EKS 获取 Kubernetes 身份验证令牌 然后可用于使用 Kubernetes SDK 向 Kubernetes 进行身份验证的身份验证令牌 换句话说 我想从 EKS 获取身份验
  • 如何更新 Dynamodb 中字符串集 (SS) 类型的项目?

    我创建了一个字符串集类型的属性 当我创建项目并分配 SS 类型的属性时 一切正常 但是当我尝试更新此属性时 数据类型更改为列表 L 我试试这个 qw new AWS DynamoDB DocumentClient var params Ta
  • jQuery UI Sortable/Draggable 导致窗口跳转

    在我的网页上 我有一个包含可排序 UL 的 div 每当我滚动到页面底部并拖动最后一个 LI 时 我的页面就会跳转 并且滚动条 在整个窗口上 会增长 这是一个几乎解决了我的问题的 JSFiddle www jsfiddle net u5af
  • 在Django中的特定时间执行任务

    我必须在用户指定的特定时间执行任务 这不会是固定时间 它将根据用户 到时候我就得执行我的任务了 为了实现这一点 我尝试使用 django cron 也尝试使用 django crontab 但在这两种情况下 我们都必须在中指定 cron 详
  • 源代码控制政策

    我正在寻找不同源代码控制策略的概述 我只了解到主线政策 并希望在加入团队之前更好地了解其他政策 有人可以提供一个概述的链接 甚至给我一些政策名称 以便我可以启动谷歌吗 没有空的提交消息
  • 如何将内存流加载到 LibVLC 中?

    我想使用 LibVLC 播放内存流中的媒体文件 如下所示 Ideally it would go like this LibVLC MediaFromStream new MemoryStream File ReadAllBytes Fil
  • Javascript 中的通配符字符串比较

    假设我有一个包含许多字符串的数组 称为 birdBlue birdRed 和其他一些动物 比如 pig1 pig2 现在我运行一个 for 循环来遍历数组并应该返回所有鸟类 这里什么样的比较才有意义 Animals bird 这是我的第一个
  • 什么时候应该真正使用访问者模式

    在文中我什么时候应该使用访客设计模式 https stackoverflow com questions 255214 when should i use the visitor design pattern第一个回答者指出 现在我们要向层
  • 使用airflow hive操作符并输出到文本文件

    您好 我想使用气流 hive 运算符执行 hive 查询并将结果输出到文件 我不想在这里使用 INSERT OVERWRITE hive ex HiveOperator task id hive ex hql sql hive ex sql
  • Swift 2 AVPlayer - 播放下一个视频上一个视频

    我对这一部分的研究已经不止一天了 请提出任何想法 我必须完成播放视频 我有一个视频列表 如果用户将其设为全屏视频 则上一个和下一个播放器按钮将启用 并在单击时播放 这是我的代码 var commmentQueuePlayer AVQueue
  • Java 接口和 Objective-C 协议之间的区别?

    我了解 Java 现在正在学习 Objective C Java 接口和 Objective C 协议到底有什么区别 首先 一点点关于该主题的历史观点 http www virtualschool edu objectivec influe
  • 为什么参数处于逆变位置?

    我试图在特征中使用协变类型参数来构造一个案例类 如下所示 trait MyTrait T private case class MyClass c T 编译器说 error covariant type T occurs in contra
  • 使用 Scala 延续实现收益(收益回报)

    如何实现 C yield return使用 Scala 延续 我希望能够编写 ScalaIterator风格相同 评论里有刺这篇 Scala 新闻文章 http www scala lang org node 2096 但它不起作用 尝试使