如何在斯卡拉选项值相结合?

问题描述 投票:28回答:6

我希望能够运用的操作f: (T,T) => T在斯卡拉Option[T]值。我想要的结果是None如果任何两个值是None

更具体地讲,我想知道是否有一个较短的方式来做到以下几点:

def opt_apply[T](f: (T,T) => T, x: Option[T], y: Option[T]): Option[T] = {
  (x,y) match {
    case (Some(u),Some(v)) => Some(f(u,v))
    case _ => None
  }
}

我曾尝试qazxsw POI但结果是qazxsw POI不是(x zip y) map {case (u,v) => f(u,v)}

scala type-conversion scalaz
6个回答
32
投票
Iterator[T]

19
投票

@ RahulG的答案利用这样的事实Option[T]是一个单子(即使是没有类型在Scala库,以表示此)。编译器扩展scala> val (x, y) = (Some(4), Some(9)) x: Some[Int] = Some(4) y: Some[Int] = Some(9) scala> def f(x: Int, y: Int) = Math.max(x, y) f: (x: Int,y: Int)Int scala> for { x0 <- x; y0 <- y } yield f(x0, y0) res26: Option[Int] = Some(9) scala> val x = None x: None.type = None scala> for { x0 <- x; y0 <- y } yield f(x0, y0) res27: Option[Int] = None 理解以下几点:

Option

你也可以把它当作一个适用函子,从Scalaz一些帮助:

for

一个关键的区别是,在一元计算,计算的故障(即,def a: Option[Int] def b: Option[Int] val calc: Option[Int] = a flatMap {aa => b map {bb => aa + bb}} import scalaz._ import Scalaz._ def a: Option[Int] def b: Option[Int] val calc: Option[Int] = (a ⊛ b) {_ + _} 短路评价。在应用性的风格,既Nonea进行评估,并且如果两者都as,纯函数被调用。你也可以看到,在一元计算,价值b可能已经在计算Some使用;在应用性的版本,aa不能依赖于b的结果。


3
投票

我有一个稍微旧版本scalaz比返璞词,但对我来说,以下的作品作为一个例子,是普及的,你有3种类型b并不仅仅是一个情况:

a

然后我可以添加:

T, U, V

1
投票

您可以使用内涵:

def main(args: Array[String]) {
  import scalaz._
  import Scalaz._

  val opt1 = some(4.0) //Option[Double]
  val opt2 = some(3)   //Option[Int]

  val f: (Double, Int) => String = (d, i) => "[%d and %.2f]".format(i, d)

  val res = (opt1 <|*|> opt2).map(f.tupled)
  println(res) //Some([3 and 4.00])
}

这是糖:

val opt3 = none[Int]
val res2 = (opt1 <|*|> opt3).map(f.tupled)
println(res2) //None

这也是可能的,因为期权是一个单子


0
投票
def opt_apply[T](f: (T,T) => T, x: Option[T], y: Option[T]): Option[T] = 
     for (xp <- x; yp <- y) yield (f(xp,yp))

x flatMap {xp => y map {yp => f(xp, yp)}} 不会导致可迭代[(A,B)](带有的,因为它从选项是,至多一个元素)。 def optApply[A,B,C](f: (A, B) => C, a: Option[A], b: Option[B]): Option[C] = a.zip(b).headOption.map { tup => f.tupled(tup) } 然后返回第一个元件作为一个选项。


0
投票

开始a.zip(b)headOption可以应用到另一个Scala 2.13返回一个Option#zip(在早期版本中,它会返回一个Option);从而:

Option

其中Iterable的行为是:

def optApply[T](f: (T,T) => T, a: Option[T], b: Option[T]): Option[T] =
  a.zip(b).map(f.tupled)

并且其可以被应用为这样的:

zip
© www.soinside.com 2019 - 2024. All rights reserved.