我最初在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
}
我对上面的代码不满意,因为它重复且难以阅读/维护。有没有更好的方法可以做到这一点?我试图通过模式匹配值来搜索如何组合函数,但没有找到任何工作。看起来我不知道正确的术语。
任何帮助都会受到赞赏,如果有更好的措辞,请随时更改标题。
之前感谢:)
答案 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
的所有结果的总和。