Scala tuple function composition

Let's say we have 3 functions with the result 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")
}

      

And I can compose them like this:

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

      

But I want something like this:

val (x, y, z) = foo(bar(buz("1", "2", "3")))

      

How can I achieve this?

+3


source to share


3 answers


I think this is what you want.

foo _ tupled(bar _ tupled buz("1", "2", "3"))
// res0: (String, String, String) = (foo_bar_buz_1,foo_bar_buz_2,foo_bar_buz_3)

      



First, use the eta ( _

) extension to turn the method into Function

. You can then call its method tupled()

, which takes a tuple and turns it into the required arguments.

+4


source


For ease of input, imagine we have the following type alias:

type String3 = (String, String, String)

      

You can use andThen

or compose

as sheunis said and you can include Function3[String, String, String, String3]

in Function1[String3, String3]

with a function tupled

. Then, combined with the eta extension, you get this:

val buzBarFoo = (buz _ tupled) andThen (bar _ tupled) andThen (foo _ tupled)

      

or that:



val buzBarFoo = (foo _ tupled) compose (bar _ tupled) compose (buz _ tupled)

      

Which both are of the above type Function1[String3, String3]

Then you can use the function as before:

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

      

+4


source


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")

      

There are two functions for this: andThen

and compose

. They are only defined on Function1

, which you can create by passing tuples to your methods.

+1


source







All Articles