如何将函数应用于 Scala 中的选项列表?

How to apply function to list of options in Scala?

假设我有一个函数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))

你会如何实施它?

您可以将 Optiontakeflattencollect 一起使用以获得一个非常干净的版本:

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)
}
如果前三个元素是 Some

ois.take(3).flatten 只会匹配 List(a,b,c)。您将变量包装在 Option 中以启用所需的 collect 语义(这样部分函数 miss 将 return None 和部分函数的 return将包裹在 Some).