我很想知道爲什麼scala.Either
不是作爲monad完成的設計決定。已經存在關於如何正確的偏置Either
,例如一些討論:爲什麼斯卡拉不是一個monad?
但也有提到太多細節,我不能讓完整地瞭解它爲什麼完成的原因。有人可以概述一下正確的偏好Either
,關於這樣做的問題以及沒有正確的偏好Either
(如果他們甚至存在)的好處嗎?
我很想知道爲什麼scala.Either
不是作爲monad完成的設計決定。已經存在關於如何正確的偏置Either
,例如一些討論:爲什麼斯卡拉不是一個monad?
但也有提到太多細節,我不能讓完整地瞭解它爲什麼完成的原因。有人可以概述一下正確的偏好Either
,關於這樣做的問題以及沒有正確的偏好Either
(如果他們甚至存在)的好處嗎?
我認爲它只是歸結爲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
是失敗的情況下,所以這是結果,但想象如果Either
是Right
-偏置。上面的代碼將編譯沒有.right
預測中的表達,如:
for (a <- foo(); b <- bar(a); c <- baz(b)) yield c
如果你在代碼中使用Either
僅僅是一個「一或-的 - 其他」類型,則可以通過將感到驚訝(1 )這將編譯的事實和(2)它返回Left(1)
並且看起來從不執行baz
。
總之,如果您想使用Either
來編碼成功或失敗,請使用Validation
。
+1這個令人印象深刻的例子。 – Frank
我不知道這是否是原因,但至少有一個很好的理由。在斯卡拉,for
理解需要更多的參數,而不是它是一個monad爲了獲得完整的功能。特別是,有喜歡
for (a <- ma if a > 7; /*...*/) yield /*...*/
結構需要的單子是一個單子,用零(所以如果條件不滿足,你可以清空)。
Either
不能明顯地是一個零單子(除了Either[Unit,B]
,其中Left(())
可以是零)。
一種方法是說:好吧,好吧,就是不要用這種方式來理解。另一種方式是說:好吧,好吧,不要打擾做一個monad。當然,這是一個個人喜好的問題,但是我可以看到,當你嘗試使用全功率for
給你時,在它的臉上會出現Either
(在Scala中提供的常見單子之一中獨一無二)的優雅。
沒有真正回答這個問題,但是如果您查看Scalaz的「驗證」,這似乎是您要查找的內容,或多或少。 – adelbertc