Scala元组函数组合

3

假设我们有三个返回Tuple3的函数:

def foo(a: String, b: String, c: String): (String, String, String) = {
  (s"foo_$a", s"foo_$b", s"foo_$c")
}

def bar(a: String, b: String, c: String): (String, String, String) = {
  (s"bar_$a", s"bar_$b", s"bar_$c")
}

def buz(a: String, b: String, c: String): (String, String, String) = {
  (s"buz_$a", s"buz_$b", s"buz_$c")
}

我可以像这样组成它们:

val (a, b, c) = foo("1", "2", "3")
val (d, e, f) = bar(a, b, c)
val (g, h, i) = buz(d, e, f)

但是我想要像这样的东西:
val (x, y, z) = foo(bar(buz("1", "2", "3")))

我该如何实现这个目标?
3个回答

4
我想这就是你所需要的。
注:该句为HTML标签,无需翻译。
foo _ tupled(bar _ tupled buz("1", "2", "3"))
// res0: (String, String, String) = (foo_bar_buz_1,foo_bar_buz_2,foo_bar_buz_3)

首先,使用 eta 扩展(_)将该方法转换为 Function。然后可以调用其 tupled() 方法,该方法接受一个元组并将其转换为所需的参数。


3

为了方便输入,假设我们定义了以下类型别名:

type String3 = (String, String, String)

你可以像sheunis所说的那样使用andThencompose,你可以使用tupled函数将一个Function3[String, String, String, String3]转换为一个Function1[String3, String3]。然后与eta扩展组合使用,你会得到这个:
val buzBarFoo = (buz _ tupled) andThen (bar _ tupled) andThen (foo _ tupled)

或者这样:
val buzBarFoo = (foo _ tupled) compose (bar _ tupled) compose (buz _ tupled)

这两个都具有前面提到的Function1[String3, String3]类型的函数。

然后,您可以像以前一样使用此函数:

val (x, y, z) = buzBarFoo("1", "2", "3")

1
def foo(arg: (String, String, String)): (String, String, String) = {
  (s"foo_${arg._1}", s"foo_${arg._2}", s"foo_${arg._3}")
}

def bar(arg: (String, String, String)): (String, String, String) = {
  (s"bar_${arg._1}", s"bar_${arg._2}", s"bar_${arg._3}")
}

def buz(arg: (String, String, String)): (String, String, String) = {
  (s"buz_${arg._1}", s"buz_${arg._2}", s"buz_${arg._3}")
}

val (a, b, c) = foo("1", "2", "3")
val (d, e, f) = bar(a, b, c)
val (g, h, i) = buz(d, e, f)

val newFunc = foo _ andThen bar andThen buz
newFunc("1", "2", "3")

有两个函数,andThencompose,它们可以实现这一功能。它们只在Function1 上定义,可以通过将元组传递给方法来创建。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接