给出以下类型:
sealed trait Pet {
val name: String
}
case class Dog(override val name: String) extends Pet
case class Cat(override val name: String) extends Pet
sealed trait Error
case object DBConnection extends Error
case object NoResults extends Error
Run Code Online (Sandbox Code Playgroud)
我们编写了一个按名称搜索宠物的函数.
def foo(petName: String): Either[Error, Pet] = {
val results: Either[Error, List[Pet]] = ??? // does not matter
val foundPet: Option[Pet] = results match {
case left @ Left(_) => None
case Right(ps) => ps.find(_.name == petName)
}
foundPet match {
case None => Left(NoResults)
case Some(p) => Right(p)
}
}
Run Code Online (Sandbox Code Playgroud)
请忽略有关数据库调用的上述代码的任何改进.
理想情况下,我更喜欢将上面的代码写成一个简单的for comprehension,利用Eithermonad.我相信,模式匹配很容易阅读,但for我怀疑,替代方案会更简洁.
如何用for-comprehension重写上面的代码?我想我可以制作匹配返回类型的方法Either[Error, Pet],但不确定.
问题是Scala Either不是monad并且它没有偏见因此你不能在for-comprehension中使用它:你必须首先得到一个LeftProject或RightProjection,就像其他海报一样.
如果你开放的话scalaz.scalaz disjunction(\/)是正确的偏见并遵循所有monad法则.当你map超过它它给你right价值.
所以你的类型将成为
val results : \/[Error,List[Pet]]
Run Code Online (Sandbox Code Playgroud)
并且 results.map会给你List[Pet]因为斯卡拉兹分离是正确的偏见.
这可能也有帮助
| 归档时间: |
|
| 查看次数: |
500 次 |
| 最近记录: |