- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在努力解决 scala 延续的复杂打字问题。我一直在阅读我能找到的所有 Material ,包括关于 continuations 包的引用文档。我想我已经在某种程度上弄清楚了,当你考虑它时它是有道理的。
我认为我对它的理解(以及我的一些问题)可以通过这个程序得到最好的总结:
package com.whatever;
import scala.util.continuations._;
object methods {
/* The method takes an Int as its parameter. Theoretically, at some point in the future,
* it will return a Float to the remainder of the continuation. This example does it
* immediately but doesn't have to (for example it could be calling a network service
* to do the transformation)
*
* Float @cpsParam[Unit,Float] means that whatever part of the reset{} that is captured
* as a closure should receive a Float and needn't return anything (would it be meaningful
* if Unit were something else?)
*
* The reason I have to return 0.toFloat is so the compiler can properly type the
* method. That zero will never go anywhere. Is this a sign I'm doing it wrong?
*/
def method1(param:Int): Float @cpsParam[Unit,Float] = shift { cb:(Float=>Unit) =>
cb(param.toFloat);
0.toFloat;
}
/* This method is basically identical but returns a String instead of a Float (Again,
* theoretically this would be done by a network service and cb would be called at some
* point in the future.
*/
def method2(param:Int): String @cpsParam[Unit,String] = shift { cb:(String=>Unit) =>
cb(param.toString);
""
}
}
object Main {
def main(args:Array[String]):Unit = {
reset {
val f = methods.method1(5);
println(f);
}
}
}
Unit
如 B
在 @cpsParam[B,C]
? "5.0"
)。但是,我现在遇到的导致我困惑的问题是当我更改 reset
时阻止尝试拨打 method2
之后 method1
:reset {
val f = methods.method1(5);
println(f);
val s = methods.method2(42);
println(s);
}
illegal answer type modification: scala.util.continuations.cpsParam[Unit,Float] andThen scala.util.continuations.cpsParam[Unit,String]
最佳答案
在我问了这个问题之后,我做了更多的研究,我想我现在可以回答我自己的问题了(我希望这不是失礼)。
我做了三件事帮助我理解了这个问题,我认为任何在 Scala 的延续方面遇到问题的人都可以很好地遵循以下步骤:
shift
的类型签名并注意它在做什么。这将把你带到我的顿悟。 @cpsParam
s 和
cb
shift
的参数都错了。我将解释我如何找出我做错了什么,以便其他像我一样愚蠢的人可以遵循相同的步骤,并希望在延续编译器让他们发疯时获得一些见解。
reset
以回调传递风格阻止,假装它不是
shift
,每个方法都有一个名为
cb
的第二个参数这将需要一个函数来完成块的其余部分。这是重置块之后的样子:
methods.method1(5, {f: Int => {
println(f);
methods.method2(42, {s: String => {
println(s);
});
});
Unit
否则它们会污染它们被传入的方法的返回类型。我认为这就是编译器试图告诉我的(尽管我可能是错的)。
method1
必须看起来像我的回调式程序
def method1(param:Int, cb:(Float=>Unit)):Unit = {
cb(param.toFloat);
}
method2
是相似的,但需要一个
(String=>Unit)
.现在很明显我的方法也应该返回
Unit
否则它们可能会污染回调函数的返回类型。
shift
只捕获到下一个
shift
作为延续。当然,事实并非如此。每个
shift
必须捕获
reset
的全部其余部分块包括以下所有
shift
s 以便它形成一个大的嵌套回调中的回调情况。此外,所有回调和所有 CPS 调用的方法应该总是(据我所知)返回
Unit
,因为它们的结果不仅不会做任何事情,而且可能会污染调用它们的函数的返回类型,等等。
shift
的签名.它就在我面前:
def shift[A,B,C](fun: (A => B) => C)): A @cpsParam[B,C]
shift
在幕后做了什么)基本上可以把它变成一个维度分析的练习。
method1
的结果将是
Float
.因此,继续回调(在上面表示为
(A => B)
)需要接受
Float
作为其参数。这修复了
A
如
Float
.因此
method1
现在看起来像这样:
def method1(param:Int): Float @cpsParam[B,C] = shift { cb: (Float => B) => {
...
C
}
}
shift
的函数必须将一个函数从 Float 带到 B,然后返回 C。好吧,我从我的练习中知道回调应该返回 Unit 否则事情会变得困惑。我也知道在我的回调练习中,方法本身显然应该返回
Unit
因为他们将实际结果作为参数传递给延续。这类似于 C 也是单位。所以这意味着
method1
必须是这样的:
def method1(param:Int): Float @cpsParam[Unit,Unit] = shift { cb: (Float => Unit) => {
cb(param);
}
}
method2
除了回调将采用字符串之外,将是相同的。
Unit
因为任何结果都作为参数传递而不是返回。
B
没有太大的意义。和
C
在
shift
不是
Unit
.这是完全合理的,因为有一个注释
@suspendable
这是
@cps[Unit]
的快捷方式这是
@cpsParam[Unit,Unit]
的快捷方式.
MyReturnType @suspendable
以外的任何东西,那么你可能做错了,顺便说一句,
shift
所采用的函数参数也应该返回
Unit
。”那样的话,我还有生命中最后几天宝贵的时光。
关于Scala 延续 : many shifts in sequence,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9487051/
我有一些 Scala 代码,它用两个不同版本的类型参数化函数做了一些漂亮的事情。我已经从我的应用程序中简化了很多,但最后我的代码充满了形式 w(f[Int],f[Double]) 的调用。哪里w()是
如果我在同一目录中有两个单独的未编译的 scala 文件: // hello.scala object hello { def world() = println("hello world") }
val schema = df.schema val x = df.flatMap(r => (0 until schema.length).map { idx => ((idx, r.g
环境: Play 2.3.0/Scala 2.11.1/IntelliJ 13.1 我使用 Typesafe Activator 1.2.1 用 Scala 2.11.1 创建一个新项目。项目创建好后
我只是想知道如何使用我自己的类扩展 Scala 控制台和“脚本”运行程序,以便我可以通过使用实际的 Scala 语言与其通信来实际使用我的代码?我应将 jar 放在哪里,以便无需临时配置即可从每个 S
我已经根据 README.md 文件安装了 ensime,但是,我在低级 ensime-server 缓冲区中出现以下错误: 信息: fatal error :scala.tools.nsc.Miss
我正在阅读《Scala 编程》一书。在书中,它说“一个函数文字被编译成一个类,当在运行时实例化时它是一个函数值”。并且它提到“函数值是对象,因此您可以根据需要将它们存储在变量中”。 所以我尝试检查函数
我有 hello world scala native 应用程序,想对此应用程序运行小型 scala 测试我使用通常的测试命令,但它抛出异常: NativeMain.scala object Nati
有few resources在网络上,在编写与代码模式匹配的 Scala 编译器插件方面很有指导意义,但这些对生成代码(构建符号树)没有帮助。我应该从哪里开始弄清楚如何做到这一点? (如果有比手动构建
我是 Scala 的新手。但是,我用 创建了一个中等大小的程序。斯卡拉 2.9.0 .现在我想使用一个仅适用于 的开源库斯卡拉 2.7.7 . 是吗可能 在我的 Scala 2.9.0 程序中使用这个
有没有办法在 Scala 2.11 中使用 scala-pickling? 我在 sonatype 存储库中尝试了唯一的 scala-pickling_2.11 工件,但它似乎不起作用。我收到消息:
这与命令行编译器选项无关。如何以编程方式获取代码内的 Scala 版本? 或者,Eclipse Scala 插件 v2 在哪里存储 scalac 的路径? 最佳答案 这无需访问 scala-compi
我正在阅读《Scala 编程》一书,并在第 6 章中的类 Rational 实现中遇到了一些问题。 这是我的 Rational 类的初始版本(基于本书) class Rational(numerato
我是 Scala 新手,我正在尝试开发一个使用自定义库的小项目。我在库内创建了一个mysql连接池。这是我的库的build.sbt organization := "com.learn" name :
我正在尝试运行一些 Scala 代码,只是暂时打印出“Hello”,但我希望在 SBT 项目中编译 Scala 代码之前运行 Scala 代码。我发现在 build.sbt 中有以下工作。 compi
Here链接到 maven Scala 插件使用。但没有提到它使用的究竟是什么 Scala 版本。我创建了具有以下配置的 Maven Scala 项目: org.scala-tools
我对 Scala 还很陌生,请多多包涵。我有一堆包裹在一个大数组中的 future 。 future 已经完成了查看几 TB 数据的辛勤工作,在我的应用程序结束时,我想总结上述 future 的所有结
我有一个 scala 宏,它依赖于通过包含其位置的静态字符串指定的任意 xml 文件。 def myMacro(path: String) = macro myMacroImpl def myMacr
这是我的功能: def sumOfSquaresOfOdd(in: Seq[Int]): Int = { in.filter(_%2==1).map(_*_).reduce(_+_) } 为什么我
这个问题在这里已经有了答案: Calculating the difference between two Java date instances (45 个答案) 关闭 5 年前。 所以我有一个这
我是一名优秀的程序员,十分优秀!