# How to map an n-arity function to 1-arity function of tuple

If I have a function one some arity, say `n`, and I want to convert it to a unary function, what is the best way to do it? Do I need to write it by hand every time, or is there an operator I can use?

For example, suppose I have a function like,

``````def f(x1:A1, x2: A2, ... xn:An):B = {
...
}
``````

and I need to give this function to a `map`, `hashMap`, `fold` etc, which is expecting a tuple of type `((A1,A2,...An)) => B`

Is there a function such as `n-arity-function-to-appropriate-tuple-function` ?

I think I’ve almost found the answer. From tupled/untupled

I can’t use the syntax `f.tupled`, but I can use `(f _).tupled`.
However, I cannot figure out how to use `untupled` at all.

``````import Function._

def f(src:Int,edges:List[(Int,Int)]):(Int,List[Int]) = {
(src, edges.map(_._2))
}

val x1 = f.utpled
val x2 = (f _).tupled

val y1 = x1.untupled
val y2 = (x1 _).untupled
``````

Which is colorized in IntelliJ as follows. You can use `Function.tupled(f _)` and `Function.untupled(f _)`.

How is `Function.tupled(f _)` different from `(f _).tupled` ?

In the first, `tupled` is a method defined on the object `Function`. In the second, `tupled` is a method defined on a trait `FunctionN` where `N` is equal to the arity of method `f`.

For `tupled` it doesn’t really make a difference, but `untupled` only exists in the `Function` object.

1 Like

Interesting error when I true to use it in its syntactically correct form.

``````import Function._

def f(src:Int,edges:List[(Int,Int)]):(Int,List[Int]) = {
(src, edges.map(_._2))
}
val x1 = tupled(f _)
val y1 = untupled(x1 _)
``````
``````Error:(7, 18) overloaded method value untupled with alternatives:
[a1, a2, a3, a4, a5, b](f: ((a1, a2, a3, a4, a5)) => b)(a1, a2, a3, a4, a5) => b <and>
[a1, a2, a3, a4, b](f: ((a1, a2, a3, a4)) => b)(a1, a2, a3, a4) => b <and>
[a1, a2, a3, b](f: ((a1, a2, a3)) => b)(a1, a2, a3) => b <and>
[a1, a2, b](f: ((a1, a2)) => b)(a1, a2) => b
cannot be applied to (() => ((Int, List[(Int, Int)])) => (Int, List[Int]))
val y1 = untupled(x1 _)
``````

I think `untupled(x1)` should work. `x1` is already a function object.

1 Like

To be precise, here `f` is a method, not a function. Syntax construct `f _` in turn is described as lifting method `f` to a function.

Just to recap a couple of things of interest here, you must keep in mind that

• methods and functions are not the same in scala
• a method is defined on an object instance
• a function is an object in his own right with a specific method called apply, that allow you to… “apply the function” to some arguments, using a shorthand syntax that makes its use similar to methods

This subtle difference gives rise to a lot of puzzling behaviour, as most function operators are not valid for methods. That’s when the `f _` syntax is used to “lift the method as a function object”.

Further confusion is due to the fact that there exists usages when the lifting is implicitly done by the compiler, if the context makes it clear that you expected a function and a method with matching parameters is passed (e.g. higher order functions like `map, fold`)

You can find additional information in this useful article

1 Like