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

如何将函数应用于Scala中的选项列表?,scala,scalaz,applicative,Scala,Scalaz,Applicative,假设我有一个函数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.s

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

您将如何实现它?

您可以使用
选项
获取
展平
,以及
收集
来获得一个非常干净的版本:

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)。如果前三个元素是
某些
,则展平
将只匹配
列表(a、b、c)
。将变量包装在
选项中以启用所需的
收集
语义(这样部分函数未命中将返回
None
,部分函数的返回将包装在
部分
)。

您可以使用
选项
获取
展平
,和
一起收集
以获得一个非常干净的版本:

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)。如果前三个元素是
某些
,则展平
将只匹配
列表(a、b、c)
。将变量包装在
选项中
以启用所需的
收集
语义(这样部分函数miss将返回
,部分函数的返回将包装在
部分
)中。

如果列表的第四个元素为无,您希望得到什么结果?有了序列,你就什么也得不到了。@DidierDupont谢谢你。我错了。对于
列表(1.some,2.some,3.some,None)
我需要获得
some(f(1,2,3))
。我将更新问题。如果列表的第四个元素为“无”,您希望得到什么结果?有了序列,你就什么也得不到了。@DidierDupont谢谢你。我错了。对于
列表(1.some,2.some,3.some,None)
我需要获得
some(f(1,2,3))
。我会更新问题,谢谢。看起来很整洁!我只是想知道如果我有
List[A[Int]]
怎么办,
A
是另一个应用程序。@Michael你可以用
ois.take(3.flatte)
替换
ois.take(3.sequence
这是通用类型类的一个版本:
def foo[A[]:applicative](f:(Int,Int,Int)=>String,ois:List[A[Int]]):A[String]=ois.take(3).sequence.map{案例列表(a,b,c)=>f(a,b,c)}
(应用程序上没有
collect
,但
map
就足够了)谢谢。看起来很整洁!我只是想知道如果我有
List[A[Int]]
怎么办,
A
是另一个应用程序。@Michael你可以用
ois.take(3.flatte)
替换
ois.take(3.sequence
这是通用类型类的一个版本:
def foo[A[]:applicative](f:(Int,Int,Int)=>String,ois:List[A[Int]]):A[String]=ois.take(3).sequence.map{案例列表(a,b,c)=>f(a,b,c)}
(应用程序上没有
collect
,但
map
就足够了)