如何在Scala中的Option类型中返回多个值?

时间:2017-02-22 23:11:19

标签: scala tuples

def solve(a: Double, b: Double, c: Double): Option[(Double, Double)]= {
val disc = b*b - 4 * a * c;
val root1 = (-b + disc) / 2*a);
val root2 = (-b - disc) / 2*a);
}

我知道(root1,root2)会创建一个元组,我想在Option类型中返回元组。我想知道如何在scala中做到这一点?

2 个答案:

答案 0 :(得分:2)

其他答案涵盖了我猜你试图做的部分,但不是全部,我认为是:执行二次公式,返回一对根或{{ 1}}如果没有解决方案。鉴于此,您当前的实现也错误地计算公式。作为参考,公式为:

None

正确的实施:

x1 = (-b + sqrt(b^2 - 4ac)) / 2a
x2 = (-b - sqrt(b^2 - 4ac)) / 2a

答案 1 :(得分:0)

根据@WillD提供的答案中的评论,您似乎希望在发生异常时返回None(可能是在计算root1root2时?)在这种情况下,您可以使用scala.util.Try围绕每个计算,并将每个结果转换为Option

import scala.util.Try

def solve(a: Double, b: Double, c: Double): Option[(Double, Double)] = {
  val disc = b*b - 4 * a * c
  val root1: Option[Double] = Try((-b + disc) / (2*a)).toOption
  val root2: Option[Double] = Try((-b - disc) / (2*a)).toOption

  // If both `root1` and `root2` are calculated successfully, return the tupled values.
  for {
    r1 <- root1
    r2 <- root2
  } yield {
    (r1, r2)
  }
}

当我们使用值010调用此方法时,我们注意到发生了一些奇怪的事情:

scala> solve(0,1,0)
res0: Option[(Double, Double)] = Some((NaN,-Infinity))

我不完全确定原因,但我认为这与Double的不精确有关。希望其他人能够更好地回答为什么这会返回NaN-Infinity。但是,如果我们用Double替换所有出现的BigDecimal,我们会得到更好的精度以及所需的输出:

import scala.util.Try

def solve(a: BigDecimal, b: BigDecimal, c: BigDecimal): Option[(BigDecimal, BigDecimal)] = {
  val disc = b*b - 4 * a * c
  val root1: Option[BigDecimal] = Try((-b + disc) / (2*a)).toOption
  val root2: Option[BigDecimal] = Try((-b - disc) / (2*a)).toOption

  // If both `root1` and `root2` are calculated successfully, return the tupled values.
  for {
    r1 <- root1
    r2 <- root2
  } yield {
    (r1, r2)
  }
}

scala> solve(0,1,0)
res1: Option[(BigDecimal, BigDecimal)] = None