Flatten Scala Try

后端 未结 7 1020
天命终不由人
天命终不由人 2020-12-14 19:20

Is there a simple way to flatten a collection of try\'s to give either a success of the try values, or just the failure? For example:

def map(l:List[Int]) =          


        
相关标签:
7条回答
  • 2020-12-14 20:27

    Have a look on the liftweb Box monad. With the help of the tryo constructor function, it gives you exactly the abstraction you are looking for.

    With tryo you can lift a function into a Box. The box then either contains the result from the function or it contains an error. You can then access the box with the usual monadic helper functions (flatMap, filter, etc.), without bothering if the box contains an error or the result form the function.

    Example:

    import net.liftweb.util.Helpers.tryo
    
    List("1", "2", "not_a_number") map (x => tryo(x.toInt)) map (_ map (_ + 1 ))
    

    Results to

    List[net.liftweb.common.Box[Int]] = 
      List(
        Full(2), 
        Full(3), 
        Failure(For input string: "not_a_number",Full(java.lang.NumberFormatException: For input string: "not_a_number"),Empty)
      )
    

    You can skip the erroneous values with flatMap

    List("1", "2", "not_a_number") map (x => tryo(x.toInt)) flatMap (_ map (_ + 1 ))
    

    Results

    List[Int] = List(2, 3)
    

    There are multiple other helper methods, e.g. for combining boxes (while chaining error messages). You can find a good overview here: Box Cheat Sheet for Lift

    You can use it on its own, no need to use the whole lift framework. For the examples above I used the follwing sbt script:

    scalaVersion := "2.9.1"
    
    libraryDependencies += "net.liftweb" %% "lift-common" % "2.5-RC2"
    
    libraryDependencies += "net.liftweb" %% "lift-util" % "2.5-RC2"
    
    0 讨论(0)
提交回复
热议问题