[英]For Comprehension Example to Understand Composing Monads
J.亞伯拉罕森(J. Abrahamson)對我的“ monads-v-applicative-functors”問題作了深入解答。
我獲得了一些直覺,但我不完全理解他的有益回答。
鑒於以下Either
:
scala> x
res0: Either[String,Int] = Right(100)
scala> err
res1: Either[Boolean,Int] = Left(false)
我試圖將它們鏈接在一起:
scala> for {
| xx <- x.right
| yy <- err.right
| } yield xx + yy
res3: scala.util.Either[Any,Int] = Left(false)
但是,我當然不想要Either[Any, Int]
。 但是我們得到Any
,因為據我了解, Either[String, Int]
和Either[Boolean, Int]
的父代是Either[Any, Int]
。
在構建理解時,通常的方法是找到結束類型,即Either[String, Int]
,然后使每個flatMap
調用具有該類型嗎?
如果您是說要Either[Boolean, Int]
而不是Either[Any, Int]
,則“您不能總是得到想要的”。 組成相同(如您的示例中所示)的Either
類型(但有些其他值)都可能返回String
而不是Boolean
即使對於正確的投影也是如此:
scala> val x: Either[String,Int] = Left("aaa")
x: Either[String,Int] = Left(aaa)
scala> val r: Either[Boolean,Int] = Right(100)
r: Either[Boolean,Int] = Right(100)
scala> for {
| xx <- x.right
| yy <- r.right //you may swap xx and yy - it doesn't matter for this example, which means that flatMap could be called on any of it
| } yield yy + xx
res21: scala.util.Either[Any,Int] = Left(aaa)
因此, Either[Any,Int]
確實是正確的,並且它的終端類型盡可能小。
簡化后的版本:
scala> x.right.flatMap(xx => r.right.map(_ + xx))
res27: scala.util.Either[Any,Int] = Left(aaa)
Monad的flatMap
簽名:
flatMap[AA >: A, Y](f: (B) ⇒ Either[AA, Y]): Either[AA, Y]
通過類型:
flatMap[Any >: String, Int](f: (Int) ⇒ Either[?Boolean?, Int]): Either[Any, String]
AA >: A
在這里是完全合法的,因為它允許f = r.right.map(_ + xx)
返回大於String
left類型(因此, ?Boolean?
變成Any
),否則它甚至無法工作。 在回答您的問題時,這里的flatMap
不能具有AA = Boolean
,因為A
已經至少是String
,並且如第一個示例所示,實際上可以是String
。
而且,順便說一句,在此示例中沒有monad組成r
可能只是一個函子。 更重要的是,您在這里將RightProjection
與RightProjection
組合RightProjection
,以便它們自動進行通勤。
推斷Boolean
的唯一方法是使用Nothing
殺死String
類型-僅在確保x
始終為Right
才能這樣做:
scala> val x: Either[Nothing,Int] = Right(100)
x: Either[Nothing,Int] = Right(100)
scala> val r: Either[Boolean,Int] = Left(false)
r: Either[Boolean,Int] = Left(false)
scala> for {
| yy <- r.right
| xx <- x.right
|
| } yield yy + xx
res24: scala.util.Either[Boolean,Int] = Left(false)
然后,您當然不能放字符串,這是完全正確的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.