我一直在查看许多Scala monad变压器示例,但还没有弄清楚如何做我认为很简单的事情。我想编写一种for
理解,它在数据库(MongoDB)中查找某个东西,该返回一个Option
,然后如果Option
是Some
,则查看其内容并获取另一个Option
,依此类推。在每一步,如果我得到a None
,我都希望中止整个过程并产生类似的错误消息"X not found"
。的for
理解应该产生一个Either
(或类似的东西),其中Left
包含错误消息和一个Right
包含整个操作(可能只是一个字符串,或者使用若干沿途中获得的值的构造可能的对象)的成功结果。
到目前为止,我只是一直在Option
单独使用monad,如以下示例所示:
val docContentOpt = for {
doc <- mongoCollection.findOne(MongoDBObject("_id" -> id))
content <- doc.getAs[String]("content")
} yield content
但是,我一直试图将类似的东西集成Either
到其中。我正在寻找的是工作代码段,而不仅仅是\/
在Scalaz中尝试的建议。我试图弄清楚Scalaz的含义,但是它的文档很少,对于那些完全了解lambda微积分的人来说,似乎写的很少,我却不知道。
我会“尝试”这样的事情:
def tryOption[T](option: Option[T], message:String ="" ):Try[T] = option match {
case Some(v) => Success(v)
case None => Failure(new Exception(message))
}
val docContentOpt = for {
doc <- tryOption(mongoCollection.findOne(MongoDBObject("_id" -> id)),s"$id not found")
content <- tryOption(doc.getAs[String]("content"), "content not found")
} yield content
基本上是“尝试尝试”转换,可捕获异常中的错误。Try
是专门的右偏Either,它是单声道的(与Either相反,后者不是)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句