## Sunday, June 7, 2009

### Function.tupled, Function.curried

Scala's library hides small gems of which little is said. Let me speak of a personal favorite here, the object Function.

This object has a number of methods to construct a function from another function (or others, in the case of "chain").  They are variations of "curried", "tupled", "uncurried" and "untupled". As their names makes clear, they transform a function whose arguments are not curried or are not a tuple into a function whose arguments are curried, or which receives a tuple as an argument. Take, for instance, this definition of zipMap, which applies a function of two arguments between two lists:

`scala> def zipMap[A,B,C](l1 : Seq[A], l2 : Seq[B])(f : (A,B) => C) =     | l1 zip l2 map (x => f(x._1, x._2))zipMap: [A,B,C](l1: Seq[A],l2: Seq[B])(f: (A, B) => C)Sequence[C]scala> zipMap (List(1, 3, 9), List(5, 2, 3)) ((x,y) => x max y)res5: Sequence[Int] = List(5, 3, 9)`

This is not a bad definition, but accessing the tuple arguments to pass to f is too much mechanics for my taste. So, instead, we could do this:

`scala> def zipMap[A,B,C](l1 : Seq[A], l2 : Seq[B])(f : (A,B) => C) =     | l1 zip l2 map Function.tupled(f)zipMap: [A,B,C](l1: Seq[A],l2: Seq[B])(f: (A, B) => C)Sequence[C]scala> zipMap (List(1, 3, 9), List(5, 2, 3)) ((x,y) => x max y)res4: Sequence[Int] = List(5, 3, 9)`

Much better, don't you think? By the way, this was done on 2.8, where Seq has the method zip.

1. Wow, that was usefull!
Thx!

2. Thanks, I just looked for a way to feed my 3 arg function with tuples. It turns out with Scala 2.8 you can just use:

func.tupled

3. Too complex example.

4. Another sample

Given a list of tuples
scala> val l = List(("A",10),("B",20))
l: List[(java.lang.String, Int)] = List((A,10), (B,20))

to create instances of a case class
scala> case class Person(name:String, age:Int)
defined class Person