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.
Wow, that was usefull!
ReplyDeleteThx!
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:
ReplyDeletefunc.tupled
Too complex example.
ReplyDeleteAnother sample
ReplyDeleteGiven 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
Now instead of
scala> val p = l map {case (n,a) => Person(n,a)}
p: List[Person] = List(Person(A,10), Person(B,20))
You can also write
scala> val p = l map Person.tupled
p: List[Person] = List(Person(A,10), Person(B,20))