1

Wondering if you can comment on why following two scenarios behave differently:

The following works:

var la= List(12, 13 , 14 ,15);
var func = (x:Int) => println(x)
la.foreach(func)                   // 1
la.foreach(func(_))                // 2

But the following does not:

var la= List(12, 13 , 14 ,15);
var func1 = (x:Int) => {
    for (i <- 0 to x) yield i*2
 } mkString
la.foreach(println(func1))         // similar to 1 above
la.foreach(println(func1(_)))      // similar to 2 above

error: type mismatch; found : Unit required: Int => ? la.foreach(println(func1(_)))

duplode
  • 33,731
  • 7
  • 79
  • 150
Shalab
  • 651
  • 5
  • 6

2 Answers2

5

This case is desugared

la.foreach(println(func1(_))) 

to

la.foreach(println(x => func1(x)))

So you passing the function to println, print return type is Unit and foreach requires some Int => ? function.

In contrasting, the first sample in both cases you are feeding foreach with Int => Unit, while in the 2nd sample in both cases you are feeding foreach with Unit.

pedrofurla
  • 12,763
  • 1
  • 38
  • 49
  • I understand that by explicitly specify the argument (x) we can make it work.. but why it does not work with partially supplied argument.? In both your code bits, println is still returning Unit.. so how does it change the behavior for foreach – Shalab Nov 22 '12 at 19:14
  • It doesn't, it only doesn't type check. See how the desugaring of `func1` is different from `func` – pedrofurla Nov 22 '12 at 19:17
3

In the second code snippet, you're calling println with a function as its argument and then trying to pass the result of that call as an argument to foreach. Since println does not return a function, but foreach wants one, that does not work.

sepp2k
  • 363,768
  • 54
  • 674
  • 675