2012-09-05 63 views
5

我很想知道爲什麼scala.Either不是作爲monad完成的設計決定。已經存在關於如何正確的偏置Either,例如一些討論:爲什麼斯卡拉不是一個monad?

但也有提到太多細節,我不能讓完整地瞭解它爲什麼完成的原因。有人可以概述一下正確的偏好Either,關於這樣做的問題以及沒有正確的偏好Either(如果他們甚至存在)的好處嗎?

+0

沒有真正回答這個問題,但是如果您查看Scalaz的「驗證」,這似乎是您要查找的內容,或多或少。 – adelbertc

回答

7

我認爲它只是歸結爲Principle of Least Astonishment。使用Either來編碼成功或失敗顯然是人們所做的事情,但它並不是Either的唯一用途。事實上,除了傳統之外,沒有太多理由可以讓Right成功,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表達。這是有道理的,在bar是失敗的情況下,所以這是結果,但想象如果EitherRight-偏置。上面的代碼將編譯沒有.right預測中的表達,如:

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

如果你在代碼中使用Either僅僅是一個「一或-的 - 其他」類型,則可以通過將感到驚訝(1 )這將編譯的事實和(2)它返回Left(1)並且看起來從不執行baz

總之,如果您想使用Either來編碼成功或失敗,請使用Validation

+0

+1這個令人印象深刻的例子。 – Frank

5

我不知道這是否是原因,但至少有一個很好的理由。在斯卡拉,for理解需要更多的參數,而不是它是一個monad爲了獲得完整的功能。特別是,有喜歡

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

結構需要的單子是一個單子,用零(所以如果條件不滿足,你可以清空)。

Either不能明顯地是一個零單子(除了Either[Unit,B],其中Left(())可以是零)。

一種方法是說:好吧,好吧,就是不要用這種方式來理解。另一種方式是說:好吧,好吧,不要打擾做一個monad。當然,這是一個個人喜好的問題,但是我可以看到,當你嘗試使用全功率for給你時,在它的臉上會出現Either(在Scala中提供的常見單子之一中獨一無二)的優雅。