5

scala.Eitherなぜモナドとして行われなかったのかという設計上の決定を知りたいと思っています。右バイアスをかける方法については、すでにいくつかの議論がありますEither。たとえば、次のようになります。

しかし、あまりにも多くの詳細が言及されており、なぜそれが行われているのかについての完全な概要を得ることができませんでした。Either誰かが、右バイアスをかけることの利点、そのようにするための問題、および右バイアスを持たないことの利点Either(存在する場合でも)について概要を説明できますか?

4

2 に答える 2

8

それは、最小の驚きの原則に帰着するだけだと思います。成功または失敗をエンコードするためにを使用Eitherすることは、明らかに人々が行うことですが、 の唯一の使用法ではありませんEitherRight実際、成功したりLeft失敗したりする理由は、伝統以外にはあまりありません。上記の adelbertc のコメントにあるように、scalaz にはValidationこれを具体的にエンコードするものがあります。

上記の POLA の主張をさらに正当化するには、次のコードを使用します。

def foo(): Either[Int, Int] = Right(1)
def bar(j: Int): Either[Int, Int] = Left(1)
def baz(z: Int): Either[Int, Int] = Right(3)

// Result is Left(1) 
for (a <- foo().right; b <- bar(a).right; c <- baz(b).right) yield c

.right式で射影を使用しているため、これはコンパイルされforます。ここLeft(1)barは失敗のケースであり、それが結果EitherですRight。上記のコードは.right、次のような式のプロジェクションなしでコンパイルされます。

for (a <- foo(); b <- bar(a); c <- baz(b)) yield c

コードで単に「どちらか一方」の型を使用した場合、(1) これがコンパイルされるという事実と、(2) が返され、実行されないように見えるEitherという事実に驚かれることでしょう。Left(1)baz

要約すると、成功または失敗をエンコードするValidationために使用する場合に使用します。Either

于 2012-09-06T05:10:46.450 に答える
5

これが本来の理由かどうかはわかりませんが、少なくとも 1 つの正当な理由があります。Scala では、for内包表記は、完全な機能を得るために、引数がモナドであることよりも多くのことを必要とします。特に、次のような構造があります。

for (a <- ma if a > 7; /*...*/) yield /*...*/

これは、モナドがゼロのモナドであることを必要とします (そのため、条件が失敗した場合は空にすることができます)。

Either賢明にもゼロを持つモナドになることはできません( のために保存しEither[Unit,B]ますLeft(())。ゼロになる可能性があります)。

1 つの方法は、次のように言うことです。もう 1 つの方法は、次のように言うことです: オーケー、結構です。もちろん、これは個人的な好みの問題ですが、Either(Scala で提供される一般的なモナドの中でも特に) 与えられたすべてのパワーを使用しようとすると、その面でフラットになることには、ある程度の優雅さの欠如が見forられます。

于 2012-09-06T00:02:00.133 に答える