両方cchantepさんとマルスのは、あなたの当面の問題に良い解決策です。しかし、より広義には、どちらかといえばOption
に完全に類似したものとして扱うことは困難です。特に、理解のために潜在的に有益な計算のシーケンスを表現させることは困難です。いずれも投影API(cchantepのソリューションで使用されています)を持っていますが、少し壊れています。 (いずれかの投影がガード、パターンマッチング、または変数の割り当てを含む解読のために中断しています)。
FWIW、私はこの問題を解決するためにlibraryと書いています。それはthis APIで補う。あなたはあなたのEithersに "バイアス"を定義します。 「右偏り」は、通常のフロー(マップ、取得など)がRight
オブジェクトで表され、Left
オブジェクトが何らかの問題を表すことを意味します。 (右バイアスは従来のものですが、好きな場合は左バイアスを定義することもできますが)Either
はOption
のように扱うことができます。完全に類似したAPIをオフラインにします。
import com.mchange.leftright.BiasedEither
import BiasedEither.RightBias._
val myEither:Either[String, Object] = ...
val o = myEither.getOrElse("Substitute")
より有効に、あなたは今、すなわちflatMap、マップ、フィルタ、および内包のために使用し、どちらの真のScalaのモナドのように扱うことができます。すべての場合
val myEither : Either[String, Point] = ???
val nextEither = myEither.map(_.x) // Either[String,Int]
または
val myEither : Either[String, Point] = ???
def findGalaxyAtPoint(p : Point) : Either[String,Galaxy] = ???
val locPopPair : Either[String, (Point, Long)] = {
for {
p <- myEither
g <- findGalaxyAtPoint(p)
} yield {
(p, g.population)
}
}
を処理手順は成功しました。locPopPair
はRight[Long]
になります。何か問題が生じた場合は、最初にLeft[String]
になります。
もう少し複雑ですが、空のトークンを定義することをお勧めします。テストp.x > 1000
が失敗した場合に何が起こるか
val locPopPair : Either[String, (Point, Long)] = {
for {
p <- myEither
g <- findGalaxyAtPoint(p) if p.x > 1000
} yield {
(p, g.population)
}
}
:のは、上記の理解のために若干の変化を見てみましょうか? Left
は "空"を意味しますが、普遍的な適切な値はありません。Left
はすべてLeft[String]
ではありません。今のところ、コードはNoSuchElementException
を投げることになるでしょう。しかし、我々は空のトークンに自分自身を指定することができ、以下のように:今
import com.mchange.leftright.BiasedEither
val RightBias = BiasedEither.RightBias.withEmptyToken[String]("EMPTY")
import RightBias._
val myEither : Either[String, Point] = ???
def findGalaxyAtPoint(p : Point) : Either[String,Galaxy] = ???
val locPopPair : Either[String, (Point, Long)] = {
for {
p <- myEither
g <- findGalaxyAtPoint(p) if p.x > 1000
} yield {
(p, g.population)
}
}
、p.x > 1000
テストが失敗した場合、例外は存在しません、locPopPair
はちょうどLeft("EMPTY")
になります。
'foo'のように見えますが、' Either'ではなく 'String'を返すべきです。最後に '.getOrElse(value)'がありませんか? – Marth
「右または左に戻したいですか」は、正しい投影をマッピングすることによって行われます。 'A '、' B'の場合は 'A'(' B => A''を 'Right'とする)または' B''( 'A = Left')、あなたの友人は '.fold'です。 – cchantep
あなたが正しいです、私はあまりにも迅速に質問を読んでいます。私はちょうどその中のコードを見て、 "これをもっと簡潔に書くにはどうすればよいか"という質問をしました。私の悪い。 – Marth