gpt4 book ai didi

scala - 带返回元组的函数调用,没有中间值

转载 作者:行者123 更新时间:2023-12-03 05:06:01 25 4
gpt4 key购买 nike

我在 scala 中有一个返回元组的函数:

private def someFunction(from: List[Any], to: List[Any]): (List[Any], List[Any]) = {
// Do some stuff
(modifiedFrom, modifiedTo)
}

我想分解该元组,并将值作为参数传递给另一个函数:

@tailrec
someOtherFunction(first: List[Any], second: List[Any], third: List[Any]): Unit = {
// Some more stuff
val (two, three) = someFunction(foo, bar)
someOtherFunction(one, two, three)
}

是否可以这样写:

someOtherFunction(one, someFunction(foo,bar)) // This is a compile error.

我可以用更简洁的方式编写分解吗?

最佳答案

不太漂亮(scala 想要类型归属),但如果你真的想要一行:

def f1(): (Int, Int) = (2,3)

def f2(a: Int, b: Int, c: Int) = 0

(f2(1, _: Int, _: Int)).tupled(f1())

说明:

  • tupled 是为每个 Function 实例定义的方法(作为一等公民 lambda)。它返回一个可以接受元组的函数。

  • f2(1, _: Int, _: Int) 是一个部分应用程序 - 它从此处的第二个和第三个参数返回一个函数,因此之后可以对其进行“元组”

附注您可以通过将 f2 重新定义为来避免类型归属的丑陋:

def f2(a: Int)(b: Int, c: Int) = 0
f2(1) _ tupled f1()
<小时/>

更新。如果您不想破坏尾递归,请使用 TailCalls :

import scala.util.control.TailCalls._
def f2(a: Int)(b: Int, c: Int): TailRec[Int] =
if (false) tailcall(f2(1) _ tupled f1()) else done(0)

f2(1)(2, 3).result

这里的额外优势是,如果您的 f2 变得更加复杂 - 更容易跟踪代码中尾部定位的调用。它还支持诸如相互尾递归之类的东西。

说明:

  • tailcall 标记尾递归调用
  • done 标记要在循环结束时返回的值
  • .result 运行堆栈安全计算并从 TailCall[T] 中提取结果。您还可以注意到 TailCall 包装器与 @tailrec 起着类似的作用 - 它不允许非尾部定位调用,因为它需要“解开”结果。编译器级优化正在被蹦床计算所取代,蹦床计算也是堆栈安全的。

关于scala - 带返回元组的函数调用,没有中间值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44582873/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com