どちらの処理の失敗にスカラーコード
-
19-09-2019 - |
質問
Option
monadで表現への対策もないことScala.もう一つのニーズへのメッセージのログをと時生じるかによるスカラAPIドキュメンテーション
のどちらのタイプとしても注目され 代替scala.オプションが左 は失敗(条約) はるかのようである。
しかし、不運に見てやってください。慣行のいずれかを使いては、実世界の事例のいずれかの処理が予想される。最後に私は、以下のコードを自分自身のプロジェクト:
def logs: Array[String] = {
def props: Option[Map[String, Any]] = configAdmin.map{ ca =>
val config = ca.getConfiguration(PID, null)
config.properties getOrElse immutable.Map.empty
}
def checkType(any: Any): Option[Array[String]] = any match {
case a: Array[String] => Some(a)
case _ => None
}
def lookup: Either[(Symbol, String), Array[String]] =
for {val properties <- props.toRight('warning -> "ConfigurationAdmin service not bound").right
val logsParam <- properties.get("logs").toRight('debug -> "'logs' not defined in the configuration").right
val array <- checkType(logsParam).toRight('warning -> "unknown type of 'logs' confguration parameter").right}
yield array
lookup.fold(failure => { failure match {
case ('warning, msg) => log(LogService.WARNING, msg)
case ('debug, msg) => log(LogService.DEBUG, msg)
case _ =>
}; new Array[String](0) }, success => success)
}
(ご注意このスニペットからのリアルプロジェクトからそのまま置き換えが可能でコンパイル単独)
思いに感謝するノウハウのご利用 Either
コードおよび/またはより良いアイデアのリファクタリング上記のコードです。
解決
のいずれかが単一の意味のある結果または何を返すために使用されるオプションとは異なり、可能な2つの意味のある結果のいずれかを返すために使用されます。
分かりやすい例は、(しばらく前にScalaのメーリングリストに循環)の下に与えられます:
def throwableToLeft[T](block: => T): Either[java.lang.Throwable, T] =
try {
Right(block)
} catch {
case ex => Left(ex)
}
関数名が示すように「ブロック」の実行が成功した場合、、、それは「右(<結果>)」を返します。 Throwableがスローされた場合それ以外の場合、それは「(<スロー可能オブジェクト>)左」を返します。結果を処理するために、パターンマッチングを使用します:
var s = "hello"
throwableToLeft { s.toUpperCase } match {
case Right(s) => println(s)
case Left(e) => e.printStackTrace
}
// prints "HELLO"
s = null
throwableToLeft { s.toUpperCase } match {
case Right(s) => println(s)
case Left(e) => e.printStackTrace
}
// prints NullPointerException stack trace
希望に役立ちます。
他のヒント
Scalazライブラリーは、検証という名前のどちらかを問わず何かをしています。それは、「有効な結果または失敗のいずれかを取得する」として使用するためのいずれよりも慣用的である。
の検証はまた、誤差を蓄積することができます。
編集:「似」のどちらかの検証は、Applicativeのファンクタである、とscalazどちらかので、complettly falseで、\ /(発音「disjonction」または「どちらか」)という名前は、モナドです。 検証がエラーをaccumalateことができるという事実は、そのせい性質のものです。 \ /(「左」、それを読んで、または「エラー」)それが遭遇する - 一方、/最初で停止、自然を「早期停止」があります。完璧な説明がここにあります: http://typelevel.org/blog /2014/02/21/error-handling.htmlする
(一部の行が削除)上記のリンクのコメント、コピー/ペーストによって要求されたとおります:
// Extracting success or failure values
val s: Validation[String, Int] = 1.success
val f: Validation[String, Int] = "error".fail
// It is recommended to use fold rather than pattern matching:
val result: String = s.fold(e => "got error: " + e, s => "got success: " + s.toString)
s match {
case Success(a) => "success"
case Failure(e) => "fail"
}
// Validation is a Monad, and can be used in for comprehensions.
val k1 = for {
i <- s
j <- s
} yield i + j
k1.toOption assert_≟ Some(2)
// The first failing sub-computation fails the entire computation.
val k2 = for {
i <- f
j <- f
} yield i + j
k2.fail.toOption assert_≟ Some("error")
// Validation is also an Applicative Functor, if the type of the error side of the validation is a Semigroup.
// A number of computations are tried. If the all success, a function can combine them into a Success. If any
// of them fails, the individual errors are accumulated.
// Use the NonEmptyList semigroup to accumulate errors using the Validation Applicative Functor.
val k4 = (fNel <**> fNel){ _ + _ }
k4.fail.toOption assert_≟ some(nel1("error", "error"))
スニペット内で掲載していたり、逆.ご利用のいずれかに状況:
- このなかのデータな可能です。
- 必要なものを返しの二種類です。
旋回例外には、実は、共用。以上をtry/catchでの利用のコードとは、意味があれば例外的に 期待された結果.最も一般的取扱いにつきましては、いずれも文字列照合アルゴリズム:
result match {
case Right(res) => ...
case Left(res) => ...
}
もう一つの興味深い取扱いにつきまして Either
る場合も表示されます。を行うと、地図上コレクションが例外をスが成り立たない可能性が予想され、いくつかの情報その他にも"できない".使用のいずれかできないことなくoverburdeningのアルゴリズム
val list = (
library
\\ "books"
map (book =>
if (book \ "author" isEmpty)
Left(book)
else
Right((book \ "author" toList) map (_ text))
)
)
このリストを取得しますすべての著者、図書室、 プラス オリエンテーションをなくします。そして、さらに処理していること、そしてそ:
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
なので、基本のいずれかの利用は以下のようになります。なので特に有用なクラスがないからです。一方で、無駄なります。
猫は例外スローコードからどちらかを作成するための良い方法があります:
val either: Either[NumberFormatException, Int] =
Either.catchOnly[NumberFormatException]("abc".toInt)
// either: Either[NumberFormatException,Int] = Left(java.lang.NumberFormatException: For input string: "abc")
HTTPSで://typelevel.org/cats/datatypes/either.html#working-with-exception-y-codeする