4

我是新来的斯卡拉延续,一般相对较新的斯卡拉语言。Scala Continuations - 为什么我的移位调用不能在try-catch块中?

我尝试使用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被抛出,当用户输入“真”代码继续与my_check = true,当用户输入“假”的代码继续my_check = false,和当用户输入的字母数字字符串,其不为“真”,也不是“假”的go功能以0

然后离开我尝试用try-cat包装一些代码CH块(其中注释),并编译失败:

error: found cps expression in non-cps position

val my_check = try

我知道有一个问题,“注入”异常进入的延续,但为什么我不能简单地把里面的转移呼叫try-catch块?我需要这个在我计划的框架中,程序员不会意识到他的代码是以延续形式使用的(他会调用一些他认为是“正常”的函数,但是实际上会做shift)。

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

这个问题可以用ControlContext解决吗? 如果我在值上添加一些“打字”规则(可能是@cps [..])会有帮助吗?

我已经想过用这样演员,你不会得到该:)

感谢,

(PS我使用Scala的2.9.2,显然使用任何信贷的替代-P:continuations:enable flag)

+0

赏金将给予寻找解决方案 - 不只是为了解释为什么它不能完成... – Oren

+0

我试过想要定义一些我的框架的用户将使用的“ctry”“ccatch”,而不是标准的“try”和“catch”,但是真的很困惑。这样的解决方案将计入赏金以及:) – Oren

回答

0

Thanks @ 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-catch块与try_protector和代码将编译。

不要问我如何或为何......它看起来像编译VODOU我...

我还没有尝试过在斯卡拉2.10。

相关问题