4

필자는 스칼라 연속성에 익숙하지 않고 일반적으로 스칼라 언어에 비교적 익숙하지 않다.스칼라 연속체 - 내 시프트 된 호출을 try-catch 블록 안에 넣을 수없는 이유는 무엇입니까?

나는 스칼라 연속성을 가지고 노는 시도하고 다음 코드를 작성 :

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 = false 계속 입력하면 코드는 my_check = true 계속하고 사용자가 "사실"이나 "거짓"이 아닌 숫자 문자열을 입력 할 때 go 함수는 0

로 종료 I try-cat에서 일부 코드를 래핑하려고했습니다. 채널의 (의견이) 블록, 그리고 컴파일 실패했습니다

error: found cps expression in non-cps position

val my_check = try

나는 문제가 연속으로 예외를 "주입"과 거기에 이해하지만 왜 단순히 내부의 이동 전화를 넣을 수 없습니다 try-catch 블록?

필자가 계획하고있는 프레임 워크에서이 코드가 필요합니다. 프로그래머는 코드가 연속 형식으로 사용된다는 것을 인식하지 못합니다 (그는 "정상"이라고 생각할 수있는 기능을 호출 할 것입니다. 실제로는 shift을 수행합니다.)

필자는 이동 된 호출 자체가 예외를 발생시키지 않더라도 try-catch 블록 내에서 함수를 호출 할 수 있어야합니다.

ControlContext으로이 문제를 해결할 수 있습니까? 값에 "입력"규칙을 추가하면 도움이됩니까? (아마도 @cps [..])?

은 이미 당신이 :)

감사합니다,

가 내가 분명히 스칼라 2.9.2 사용하고있어

(PS가를 사용에 대한 신용을받지 않습니다 그래서 배우를 사용하는 다른 생각 -P : 계속 : 플래그 사용)

+0

해결책을 찾기 위해 바운티 (Bounty)가 주어질 것입니다. – Oren

+0

필자는 프레임 워크 사용자가 표준 "try"와 "catch"대신에 "ctry" "ccatch"를 정의하려고 생각했지만 실제로 혼란 스러웠습니다. 그런 해결책은 현상금을 위해 또한 의지 할 것이다 :) – Oren

답변

0

고맙습니다. @ som-snytt하지만 해결책은 일반적인 방법과 다소 다릅니다. try-catch 블록을 사용할 때마다 val my_check 대신 def 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) 
} 

을 그리고 그것은 작동한다! (scala 2.9.2에서)

사용자는 자신의 try-catch 블록을 try_protector으로 바꾸면 코드가 컴파일됩니다.

... 그것은 나에게 컴파일 VODOU처럼 보인다 ... 내가 스칼라 2.10에 그것을 시도하지 않은

을 물어 어떻게 또는 왜하지 마십시오.

관련 문제