2011-09-21 9 views
10

私はおそらくドキュメントにある何かが不足しているかもしれませんが、実際にはそれほど感覚を覚えることはできません - 私はScalaを主に試行錯誤で教えてきました。オプションとどちらのタイプを扱うか - 慣用的な変換?

与えられた関数f: A => Cは、という慣用句は次の変換を実行する方法を教えてください。

Either[A, B] -> Either[C, B]

Either[B, A] -> Either[B, C]

(私は2つのこのような機能を持っており、両側を変換したい場合は、私は一度それをすべて行うことができますか私は逐次二回イディオムを適用すべきか?)

Option[A] -> Option[C]

(これは何とかfor (...) yieldを使用していると感じていますが、私はたぶんそれを空白にしており、答えが出たらばかげて感じるでしょう)

何が正確にEitherの "投影"ですか?あなたはない

+1

以下のコメントから、「ペア」、「タプル2」と混同しているようです。それはそうではありません:「どちらか」には_one_値しか含めることができません。ある意味では、Cの 'union'と似ていますが、実際にどのメンバーが格納されているかは分かりません。 –

+0

私はそれを認識していますが、私はまだ混乱してしまいます。私はそのことをはっきりと表現していませんでした。 –

答えて

18

次のいずれか

either.left.map(f) 

か:

either.right.map(f) 

またため、理解使用することができます。for (x <- either.left) yield f(x)

はここにmapを行うためのより具体的な例ですEither[Boolean, Int]

scala> val either: Either[Boolean, Int] = Right(5) 
either: Either[Boolean, Int] = Right(5) 

scala> val e2 = either.right.map(_ > 0) 
either: Either[Boolean, Boolean] = Right(true) 

scala> e2.left.map(!_) 
either: Either[Boolean, Boolean] = Right(true) 

編集:

どのように動作しますか? Either[A, B]があるとします。 leftまたはrightを呼び出すと、Either[A, B]オブジェクトを保持するラッパーであるLeftProjectionまたはRightProjectionオブジェクトが作成されます。 leftラッパーの

、機能f: A => Cとの後続mapEither[A, B]Either[C, B]に変換するために適用されます。これは、フードの下でパターンマッチングを使用して、Eitherが実際にLeftであるかどうかをチェックすることによって行います。存在する場合は、新しいLeft[C, B]を作成します。そうでない場合は、変更するだけで、同じ基本値を持つ新しいRight[C, B]が作成されます。

rightラッパーの場合は逆になります。効果的には、either.right.map(f)と言っているのは、いずれかの(Either[A, B])オブジェクトがRightの値を保持している場合は、マップします。それ以外の場合は、そのままにしておきますが、いずれかのオブジェクトのタイプBをマップしたかのように変更します。

技術的には、これらの突起は単なるラッパーです。意味的には、Eitherオブジェクトに格納されている値がLeftまたはRightのいずれかであることを前提としていることを示す方法です。この仮定が間違っていると、マッピングは何もしませんが、型パラメータはそれに応じて変更されます。

+0

これはどのように機能しますか?予測とは何か?明らかに '.left'と' .right'はライブラリ型の "pair"型の他の言語ではそうではなく、それぞれ[A]と[B]型のメンバにアクセスします。 –

+0

あなたはその質問を見るかもしれません:http://stackoverflow.com/q/7131076/754787 –

+0

私はボンネットの下で何が起こるのか少し説明するために答えを編集しました。しかし、どちらかがペアではなく、タプル型であり、交差型(A×B')とも呼ばれます。これは、タイプ[A]または[B] - A V Bのいずれかのメンバーを保持します。これは、メンバーが1人しか存在しないため、タプルのようにどちらのメンバーにも安全にアクセスできないことを意味します。 – axel22

3

f: A=>BxOpt: Option[A]を指定すると、xOpt map fにはOption[B]が必要です。 f: A=>BxOrY: Either[A, C]考える

は、xOrY.left.map(f)Eitherあなたが探している、マッピングちょうど最初のコンポーネントを生成し;同様にRightProjectionEitherにすることができます。

2つの機能がある場合は、両方のコンポーネントのマッピングをxOrY.fold(f, g)に定義できます。

0
val e1:Either[String, Long] = Right(1) 
val e2:Either[Int,Boolean] = e1.left.map(_.size).right.map(_ >1) 
// e2: Either[Int,Boolean] = Right(false) 
関連する問題