如何编写在Scala中返回Option [List]的函数?
发布时间:2020-12-16 09:28:30 所属栏目:安全 来源:网络整理
导读:假设我有两个函数来获取订单和订单商品: def getOrders(): Option[List[Int]] = ...def getOrderItems(orderId: Int): Option[List[Int]] = ... 请注意,由于每个函数都可能失败,因此两个函数都返回Option [List]. 现在我想获得所有订单商品的清单选项,如下
假设我有两个函数来获取订单和订单商品:
def getOrders(): Option[List[Int]] = ... def getOrderItems(orderId: Int): Option[List[Int]] = ... 请注意,由于每个函数都可能失败,因此两个函数都返回Option [List]. 现在我想获得所有订单商品的清单选项,如下所示: >如果两个函数都返回Some和,则返回一些[List] 我尝试用for(参见下文)编写这些函数,但它不起作用. val allOrderItems = for { orderIds <- getOrders(); orderId <- orderIds; orderItems <- getOrderItems(orderId) } yield orderItems 如何使用函数getOrders和getOrderItems构建函数getAllOrderItems():Option [List [Int]]? 解决方法
你真的希望能够将选项[List [Option [List [Int]]]]的中间两层内部翻出来,这样你就可以得到彼此相邻的选项和列表.此操作称为排序,由Scalaz提供:
import scalaz._,Scalaz._ val items: Option[List[Int]] = getOrders.flatMap(_.map(getOrderItems).sequence).map(_.flatten) 你可以等效地使用traverse,它结合了map和sequence操作: val items: Option[List[Int]] = getOrders.flatMap(_ traverse getOrderItems).map(_.flatten) 如果您不想使用Scalaz,您可以编写自己的(更少多态)序列: def sequence[A](xs: List[Option[A]]) = xs.foldRight(Some(Nil): Option[List[A]]) { case (Some(h),Some(t)) => Some(h :: t) case _ => None } 接着: val items: Option[List[Int]] = getOrders.flatMap( orderIds => sequence(orderIds.map(getOrderItems)) ).map(_.flatten) monad转换解决方案实际上也非常简单(如果您愿意使用Scalaz): val items: Option[List[Int]] = ( for { orderId <- ListT(getOrders) itemId <- ListT(getOrderItems(orderId)) } yield itemId ).underlying 这种方法的好处在于你不必考虑你需要压扁,顺序等等 – 普通的monadic操作完全符合你的要求. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |