假设我有两个函数来获取订单和订单商品:
def getOrders(): Option[List[Int]] = ...
def getOrderItems(orderId: Int): Option[List[Int]] = ...
请注意,由于每个函数都可能失败,因此两个函数都返回 Option[List]
.
现在我想获得所有订单商品的 Option
,如下所示:
如果两个函数都返回 Some
和
-
返回
Some[List]
-
None
如果其中任何一个返回None .
我尝试用 for
(见下文)组合这些函数,但它没有用 .
val allOrderItems = for {
orderIds <- getOrders();
orderId <- orderIds;
orderItems <- getOrderItems(orderId)
} yield orderItems
如何使用函数 getOrders
和 getOrderItems
构建函数 getAllOrderItems():Option[List[Int]]
?
2 回答
你真的希望能够将
Option[List[Option[List[Int]]]]
的中间两层内部翻出来,这样你就可以获得彼此相邻的选项和列表 . 此操作称为排序,由Scalaz提供:你可以等效地使用
traverse
,它结合了map
和sequence
操作:如果您不想使用Scalaz,您可以编写自己的(更少多态)
sequence
:然后:
monad转换解决方案实际上非常简单(如果您愿意使用Scalaz):
这种方法的好处是你不必考虑你需要展平,顺序等等 - 普通的monadic操作完全符合你的要求 .
我能想到的最简单的修改如下:
for comprehension使用第一个语句来确定其余的类型 . 例如,在上面的类型
List[Int]
将被推测,这与Option[List[Int]]
不同 .