使用Scala中的选项元素的规范方法

swvgeqrz  于 2022-11-09  发布在  Scala
关注(0)|答案(3)|浏览(140)

例如,我想将函数f: (Int,Int) => Int应用于Option[Int]类型的两个元素。我的想法类似于(a,b).zipped.map(F),但这会产生一个列表,我希望得到一个新的选项[Int]作为结果。

scala> def f(a:Int,b:Int) = a*b
f: (a: Int, b: Int)Int

scala> val x = Some(42)
x: Some[Int] = Some(42)

scala> val y:Option[Int] = None
y: Option[Int] = None

scala> (x,y).zipped.map(f)//I want None as a result here
res7: Iterable[Int] = List()

没有明确的分支,如何才能做到这一点呢?

xfb7svmp

xfb7svmp1#

就像Scala中的许多其他操作一样,这可以通过for complect来完成:

def f(a:Int,b:Int) = a*b
for (x <- maybeX; y <- maybeY) yield f(x, y)
llew8vvj

llew8vvj2#

与这类问题的常见情况一样,scalaz有一些帮助:

scala> import scalaz._
import scalaz._

scala> import Scalaz._
import Scalaz._

scala> def f(a:Int,b:Int) = a*b
f: (a: Int, b: Int)Int

scala> val x = Some(42)
x: Some[Int] = Some(42)

scala> val y:Option[Int] = None
y: Option[Int] = None

scala> ^(x,y)(f)
res0: Option[Int] = None

scala> val x = 42.some
x: Option[Int] = Some(42)

scala> (x |@| y)(f)
res3: Option[Int] = None
yyhrrdl8

yyhrrdl83#

使用om-nom-nom的想法,我可以这样做:

scala> def f(a:Int,b:Int) = a*b
f: (a: Int, b: Int)Int

scala> def lifted(f: (Int,Int) => Int) = (a:Option[Int],b:Option[Int]) => for(x<-a;y<-b) yield f(x,y)
lifted: (f: (Int, Int) => Int)(Option[Int], Option[Int]) => Option[Int]

scala> def liftedF = lifted(f)
liftedF: (Option[Int], Option[Int]) => Option[Int]

scala> val x = Some(42)
x: Some[Int] = Some(42)

scala> val y:Option[Int] = None
y: Option[Int] = None

scala> liftedF(x,x)
res0: Option[Int] = Some(1764)

scala> liftedF(x,y)
res2: Option[Int] = None

我们甚至可以概括这一点……请遮住眼睛:

def lift2[A, B, C](f: (A, B) => C): (Option[A], Option[B]) => Option[C] = (a: Option[A], b: Option[B]) =>
    for (x <- a; y <- b) yield f(x, y)

相关问题