Using Either to process failures in Scala code

后端 未结 4 892
陌清茗
陌清茗 2020-11-28 03:27

Option monad is a great expressive way to deal with something-or-nothing things in Scala. But what if one needs to log a message when \"nothing\" occurs? Accord

4条回答
  •  暖寄归人
    2020-11-28 03:56

    The snippet you posted seems very contrived. You use Either in a situation where:

    1. It's not enough to just know the data isn't available.
    2. You need to return one of two distinct types.

    Turning an exception into a Left is, indeed, a common use case. Over try/catch, it has the advantage of keeping the code together, which makes sense if the exception is an expected result. The most common way of handling Either is pattern matching:

    result match {
      case Right(res) => ...
      case Left(res) => ...
    }
    

    Another interesting way of handling Either is when it appears in a collection. When doing a map over a collection, throwing an exception might not be viable, and you may want to return some information other than "not possible". Using an Either enables you to do that without overburdening the algorithm:

    val list = (
      library 
      \\ "books" 
      map (book => 
        if (book \ "author" isEmpty) 
          Left(book) 
        else 
          Right((book \ "author" toList) map (_ text))
      )
    )
    

    Here we get a list of all authors in the library, plus a list of books without an author. So we can then further process it accordingly:

    val authorCount = (
      (Map[String,Int]() /: (list filter (_ isRight) map (_.right.get))) 
       ((map, author) => map + (author -> (map.getOrElse(author, 0) + 1)))
      toList
    )
    val problemBooks = list flatMap (_.left.toSeq) // thanks to Azarov for this variation
    

    So, basic Either usage goes like that. It's not a particularly useful class, but if it were you'd have seen it before. On the other hand, it's not useless either.

提交回复
热议问题