0

I came from Java and would like to combine two partial functions like this:

def sum(a: Int, b: Int, c: Int) : Int = a + b + c

I want write something like this:

val l = List(1, 2, 3)
l.foreach(println _  sum (1, _ : Int, 3) ) // It's supposed to apply
                                  // the partial sum(1, _: Int, 3) 
                                  // and println computed value.

But it refuses to compile. Is there a way to fix it concisely?

user3663882
  • 6,957
  • 10
  • 51
  • 92
  • You are mixing up partially evaluated functions (something like `f(1,_)`) and partial functions. `sum` is a total function, not partial, this means for every domain element of the function there is one associated element in its codomain. – pedrofurla Aug 18 '16 at 16:52
  • @pedrofurla partially applied function, right. I can't compose them, can I? – user3663882 Aug 18 '16 at 16:53
  • 1
    The second line just don't make sense. Not sure it's even worth trying to explain why. – pedrofurla Aug 18 '16 at 16:53
  • Of course you can. But your code is not composing functions, it's applying value and functions and tuples, or actually trying to. – pedrofurla Aug 18 '16 at 16:54
  • Ok, I think I see what you want. – pedrofurla Aug 18 '16 at 16:55
  • @pedrofurla Why? To me, it does. I have a partially applied function which acts the same as `x -> x + 4`. I want to apply `println` to this function, i.e the resulting function would be `Int -> Unit` with side effect (printing to stdout). What's wrong? – user3663882 Aug 18 '16 at 16:55

2 Answers2

3

There are few problems with what you were trying to do. First of all, println is an overloaded method, so when you are trying to eta-expand it to a function like this println _, Scala is taking the shortest form, which is the one with 0 arguments:

scala> println _
res0: () => Unit = $$Lambda$1048/48841776@58ec44ec

So you need to be more specific:

scala> println(_: Int)
res1: Int => Unit = $$Lambda$1064/1621799037@1e8bddc4

Now that we have correct function there is one more thing to do: to add compose and proper parentheses (additional parentheses wrap anonymous functions):

scala> l.foreach((println(_: Int)) compose  (sum (1, _: Int, 3)))
5
6
7

or in the other direction:

scala> l.foreach((sum (1, _: Int, 3)) andThen (println(_: Int)))
5
6
7
Victor Moroz
  • 9,167
  • 1
  • 19
  • 23
2

Assuming I reading what you want correctly (and even the code it's a huge assumption), here a snippet that might achieve it:

scala> def sum(a: Int, b: Int, c: Int) : Int = a + b + c
sum: (a: Int, b: Int, c: Int)Int

scala> val sum13 = sum(1, _ : Int, 3)
sum13: Int => Int = <function1>

scala> val printInt = println( _ : Int )
printInt: Int => Unit = <function1>

scala> List(1,2,4) foreach { printInt compose sum13 }
5
6
8

Notice the compose. Another way would be explicitly compose x => printInt(sum13(x)).

pedrofurla
  • 12,763
  • 1
  • 38
  • 49