Scala continuation and exception handling

后端 未结 3 1947
没有蜡笔的小新
没有蜡笔的小新 2021-02-14 16:03

Suppose, I would like to catch an exception, fix the problem caused the exception and return to the same execution point where the exception occurred to continue.

How ca

3条回答
  •  谎友^
    谎友^ (楼主)
    2021-02-14 16:26

    Here is one of the possible ways of implementing resumable error handling:

    import java.io.File
    import java.lang.IllegalStateException
    import scala.util.continuations._
    
    // how it works
    
    ctry {
      println("start")
    
      val operationResult = someOperation(new File("c:\\ttttest"))
    
      println("end " + operationResult)
    } ccatch {
      case (DirNotExists(dir), resume) =>
        println("Handling error")
        dir.mkdirs()
        resume()
    }
    
    def someOperation(dir: File) = {
      cthrow(DirNotExists(dir))
      println(dir.getAbsolutePath + " " + dir.exists)
      "Operation finished"
    }
    
    // exceptions
    
    trait CException
    case class DirNotExists(file: File) extends CException
    
    // ctry/ccatch classes and methods
    
    sealed trait CTryResult[T] {
      def get: T
      def ccatch(fn: PartialFunction[(CException, () => T), T]): T
    }
    case class COk[T](value: T) extends CTryResult[T] {
      def ccatch(fn: PartialFunction[(CException, () => T), T]) = value
      def get = value
    }
    case class CProblem[T](e: CException, k: Any => Any) extends CTryResult[T] {
      def ccatch(fn: PartialFunction[(CException, () => T), T]) = 
              fn((e, () => k(Unit).asInstanceOf[T]))
      def get = throw new IllegalStateException("Exception was not processed: " + e)
    }
    
    def ctry[T](body: => T @cps[Any]) = reset (body) match {
      case (e: CException, k: (Any => Any)) => CProblem[T](e, k)
      case value => COk(value)
    }
    
    def cthrow(e: CException): Any @cps[Any] = shift((k: Any => Any) => (e, k))
    

    This code produces following output:

    start 
    Handling error
    c:\ttttest true
    end Operation finished
    

提交回复
热议问题