包含选项的列表/数组

时间:2014-11-20 18:36:09

标签: scala monads optional

哪种做法更好?有可选列表或列表中有可选项吗?

目前我正在关注一个可选列表。

列出[选项[T]]或选项[列表[T]]?

修改

我遇到的问题是,我有从不返回可选类型的crud操作。我有一种情况,我有一个方法,只进行一次查找,我想利用它来创建一个返回列表的函数。我还在用scala弄湿我的脚,所以我很好奇最佳做法是什么。

示例:

def findOne(id: Int): Option[T]

无论实现如何,我都希望将它用于类似的东西,但哪个更好?它们似乎都很奇怪。也许有一些我一起失踪的东西:

def find(ids: List[Int]) : Option[List[T]]

VS

def find(ids: List[Int]) : List[Option[T]]

3 个答案:

答案 0 :(得分:6)

这两种类型意味着非常不同的东西。 List[Option[T]]看起来像是flatten的中间结果。 (在这种情况下,我会考虑使用flatMap。)

第二种类型Option[List[T]]表示可能有也可能没有列表。当您需要区分“无结果”案例和“结果是空列表”案例时,这将是一个很好的类型。

我无法想到这两种类型都有意义的情况。

答案 1 :(得分:1)

如果你想要检索一些可能存在的东西,并且其中一些东西存在并且其中一些不存在是合理的,那么它是List[Option[T]] - 一个列表中的几个条目,每个条目是否存在。这在例如a"搜索"情况,您想要显示存在的任何一个,可能只显示一些请求的东西。您可以将该方法实现为:

def find(ids: List[Int]) = ids map findOne

如果您正在使用Option来表示类似“"错误”的内容。 case,你想要"如果其中任何一个失败那么整个事情就是失败",那么你想要Option[List[T]] - 要么是一个完整的列表,要么根本没有。你可以使用Scalaz实现它:

def find(ids: List[Int]) = ids traverse findOne

答案 2 :(得分:1)

DaoWen已经考虑到了你的考虑因素。 List[Option[T]]甚至不会编码比List[T]更多的信息,而不会隐含知道您的ID列表与结果列表的顺序相同。

我真的很喜欢

def find(ids: Seq[Int]): Seq[T]

def find(ids: Seq[Int]): Option[NonEmptyList[T]]

其中NonEmptyList是一种实际强制非空的序列,例如在Scalaz。除非你真的想指出None和一些空列表之间的区别。

顺便说一下,您可能想要使用更通用的Seq[T]代替List[T]