Sử dụng Scala 2.9.1, hãy xem xét hai trường hợp sau đây Either
:Tại sao bộ lọc Either.RightProjection # của Scala không trả về một trong hai?
scala> val er: Either[String, Int] = Right(1)
er: Either[String,Int] = Right(1)
scala> val el: Either[String, Int] = Left("a")
el: Either[String,Int] = Left(a)
Thật tuyệt vời đó, bằng cách sử dụng các left
và right
dự báo, người ta có thể sử dụng cho-comprehensions (thông qua đơn nguyên thiên vị của Hoặc dự kiến) :
scala> for { r <- er.right } yield r * 2
res6: Product with Either[String,Int] with Serializable = Right(2)
scala> for { r <- el.right } yield r * 2
res7: Product with Either[String,Int] with Serializable = Left(a)
Ai đó có thể giải thích cho tôi tại sao quyết định không được trả về phương thức filter
? Tôi đã có thể dự kiến như sau để làm việc:
scala> for { r <- er.right if r > 2 } yield r * 2 // r is NOT greater than 2!
res8: Product with Either[String,Int] with Serializable = Left(a)
Thay vào đó bạn nhận được lỗi sau: : 9: Lỗi: giá trị * không là thành viên của Hoặc [Không có gì, Int] cho {r < - er. đúng nếu r> 2} suất r * 2
Nó xuất hiện rằng cuộc gọi cơ bản trong Either.RightProjection#filter
thực sự trả về một Option
:
scala> er.right.filter(_ > 2)
res9: Option[Either[Nothing,Int]] = None
này đánh bại việc sử dụng các mệnh đề if trong cho-compre lương hưu, ít nhất là cách tôi đang cố gắng sử dụng nó.
Có ai có giải thích tại sao thiết kế này là như vậy không?
Thật là một câu trả lời tuyệt vời, có ý nghĩa tổng thể. Điều đó có nghĩa là tôi nên làm một cái gì đó như: cho {r <- er.right.filter (_> 2) .toRight ("a"). JoinRight.right} yield r * 2 –
Bạn có thể thích một mẫu phù hợp: 'er khớp với {case Right (b) nếu b> 2 => Right (b * 2); case _ => Left ("a")} ' –