Scala 延续 - 为什么我的转移呼叫不能在 try-catch 块内?



我对Scala的延续是个新手,对Scala语言总体来说还是个新手。

我试着玩Scala的续篇,并编写了以下代码:

case class MyException(msg:String) extends Exception
def go:Int = reset {
println("enter your input")
val my_check = //try 
{
val user_input = readLine()
if (!user_input.matches("\w+")) {
throw new MyException("illegal string: " + user_input) 
}
shift {
k: (Boolean => Int) => {
if (user_input == "true") {
k(true)
}
else if (user_input == "false") {
k(false)
}
else {
// don't even continue
0
}
}
}
} 
//  catch {
//    case MyException(msg) => false
//  }
if (my_check) {
println("TRUE")
1
}
else {
println("FALSE")
-1
}
}
println(go)

代码按预期工作:当用户输入非字母数字字符串时,将抛出MyException,当用户输入"true"时,代码将继续使用my_check = true,当用户键入"false"时,编码将继续使用my_check = false,而当用户输入的字母数字字符串既不是"true"也不是"false",则go函数将以0退出。

然后,我尝试将一些代码包装在try-catch块中(注释所在的位置),编译失败:

错误:在非cps位置中找到cps表达式

val my_check=尝试

我知道将异常"注入"到延续中有问题,但为什么我不能简单地将转换后的调用放入try-catch块中呢?

我在计划的框架中需要这个,在这个框架中,程序员不会意识到他的代码是以延续形式使用的(他会调用一些他认为是"正常"的函数,但实际上会执行shift)。

显然,我需要他能够调用try-catch块中的函数,即使移位的调用本身不会引发异常。

这个问题可以用ControlContext解决吗?如果我在值上添加一些"键入"规则(可能使用@cps[..]),会有帮助吗?

我已经考虑过使用Actors的替代方案,所以你不会因此获得任何赞誉:)

谢谢,

(附言:我使用的是Scala2.9.2,显然使用了-p:continuations:enable标志)

感谢@som snytt,但您的解决方案与一般解决方案相去甚远。我不能要求框架用户每次使用try-catch块时都编写def my_check而不是val my_check

然而,我使用了您的解决方案,并构建了以下代码:

import scala.util.continuations._
case class MyException(msg:String) extends Exception
object try_protector {
def apply[A,B](comp: => A @cps[B]):A @cps[B] = {
comp
}
}
object Test extends App {
def go: Int = reset {
println("enter your input")
val my_check = try_protector { 
try {
val user_input = readLine()
if (!user_input.matches("\w+")) {
throw new MyException("illegal string: " + user_input)
}
shift {
k: (Boolean => Int) => {
user_input match {
case "true"   => k(true)
case "false"  => k(false)
case _        => 0
}
}
}
} catch {
case MyException(msg) => false
}
}
if (my_check) {
println("TRUE")
1
} else {
println("FALSE")
-1
}
}
println(go)
}

它起作用了!(在标量2.9.2上)

用户只需要用try_protector包装他的try-catch块,代码就会编译。

不要问我如何或为什么。。。对我来说,这看起来像是汇编VODOU…

我还没有在scala2.10上尝试过。

相关内容

  • 没有找到相关文章

最新更新