假设我有一个函数f: (Int, Int, Int) => String
。我可以轻松地将它应用于Option[Int]
类型的三个参数:
def foo(f: (Int, Int, Int) => String,
ox: Option[Int],
oy: Option[Int],
oz: Option[Int]): Option[String] = ox <*> (oy <*> (oz <*> f.curried.some))
现在假设我需要将f
应用于列表ois: List[Option[Int]]
的前三个元素。例如:
List() => None
List(1.some, 2.some) => None
List(1.some, None, 2.some, 3.some) => None
List(1.some, 2.some, 3.some, 4.some) => Some(f(1, 2, 3))
List(1.some, 2.some, 3.some, None) => Some(f(1, 2, 3))
你会如何实现它?
答案 0 :(得分:4)
您可以将Option
,take
,flatten
和collect
一起用于一个非常干净的版本:
def foo(f: (Int, Int, Int) => String, ois: List[Option[Int]]) =
Option(ois.take(3).flatten) collect {
case List(a, b, c) => f(a, b, c)
}
如果前三个元素为ois.take(3).flatten
,则 List(a,b,c)
仅匹配Some
。您将变量包装在Option
中以启用所需的collect
语义(这样部分函数miss将返回None
,并且部分函数的返回将包含在Some
中})。