Scala中的模式匹配函数调用

时间:2016-02-04 08:44:54

标签: scala functional-programming

我最初在CodeReview上发布了这个问题,但似乎并没有适合那里。我会在这里重新开始。请告诉我它是否也适合这里,我应该在哪里发布这类问题。感谢。

我是Scala和函数式编程的新手。我想多次调用一个函数,并结合基于两个变量的参数。基本上,我现在正在做的是:

def someFunction(a: Int, b: Int): Future[Int] = ???

val value1 = true
val value2 = false

(value1, value2) match {
    case (true, true) =>
        val res1 = someFunction(0, 0)
        val res2 = someFunction(0, 1)
        val res3 = someFunction(1, 0)
        val res4 = someFunction(1, 1)

        for {
            r1 <- res1
            r2 <- res2
            r3 <- res3
            r4 <- res4
        } yield r1 + r2 + r3 + r4

    case (true, false) =>
        val res1 = someFunction(0, 0)
        val res2 = someFunction(1, 0)

        for {
            r1 <- res1
            r2 <- res2
        } yield r1 + r2

    case (false, true) =>
        val res1 = someFunction(0, 0)
        val res2 = someFunction(0, 1)

        for {
            r1 <- res1
            r2 <- res2
        } yield r1 + r2

    case (false, false) =>
        for { r1 <- someFunction(0, 0) } yield r1
}

我对上面的代码不满意,因为它重复且难以阅读/维护。有没有更好的方法可以做到这一点?我试图通过模式匹配值来搜索如何组合函数,但没有找到任何工作。看起来我不知道正确的术语。

任何帮助都会受到赞赏,如果有更好的措辞,请随时更改标题。

之前感谢:)

2 个答案:

答案 0 :(得分:5)

更简单的方法是预生成一系列参数元组:

val arguments = for {
  arg1 <- 0 to (if (value1) 1 else 0)
  arg2 <- 0 to (if (value2) 1 else 0)
} yield (arg1, arg2)

然后,您可以将参数的函数执行与Future.traverse结合起来,得到Future结果序列,然后sum结果:

Future.traverse(arguments)(Function.tupled(someFunction)).map(_.sum)

答案 1 :(得分:0)

我认为这可以解决您的问题:

def someFunction(x: Int, y: Int): Future[Int] = ???
def someFunctionTupled: ((Int, Int)) => Future[Int] = (someFunction _).tupled // Same as someFunction but you can pass in a  tuple here

def genParamList(b: Boolean) = if (b)
  List(0, 1)
else
  List(0)

val value1 = true
val value2 = false

val l1 = genParamList(value1)
val l2 = genParamList(value2)

// Combine the two parameter lists by constructing the cartesian product
val allParams = l1.foldLeft(List[(Int, Int)]()){
  case (acc, elem) => acc ++ l2.map((elem, _))
}

allParams.map((someFunction _).tupled).sum

上述代码将生成Future[Int],这是应用于someFunction列表元素的allParams的所有结果的总和。