Частично применяемые функции в Scala

Интересно, можете ли вы прокомментировать, почему следующие два сценария ведут себя по-разному:

Следующие работы:

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

Но нет следующего:

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

ошибка: несоответствие типов; найдено : Требуемая единица измерения: Int => ? la.foreach(println(func1(_)))


person Shalab    schedule 22.11.2012    source источник
comment
самая узкая невырожденная область: см. мой комментарий на stackoverflow.com/a/5259946/562716   -  person Peter Schmitz    schedule 23.11.2012


Ответы (2)


Этот случай обессахарен

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

to

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

Таким образом, вы передаете функцию println, тип возвращаемого значения печати — Unit, а foreach требует некоторой функции Int => ?.

Напротив, в первом примере в обоих случаях вы кормите foreach Int => Unit, а во втором примере в обоих случаях вы кормите foreach Unit.

person pedrofurla    schedule 22.11.2012
comment
Я понимаю, что явно указав аргумент (x), мы можем заставить его работать.. но почему это не работает с частично предоставленным аргументом.? В обоих ваших битах кода println по-прежнему возвращает Unit.. так как же это меняет поведение для foreach - person Shalab; 22.11.2012
comment
Это не так, он просто не печатает проверку. Посмотрите, чем обессахаривание func1 отличается от func - person pedrofurla; 22.11.2012

Во втором фрагменте кода вы вызываете println с функцией в качестве аргумента, а затем пытаетесь передать результат этого вызова в качестве аргумента в foreach. Поскольку println не возвращает функцию, а foreach хочет ее, это не работает.

person sepp2k    schedule 22.11.2012
comment
Спасибо! как мы можем исправить это, но все еще используя частично предоставленный аргумент? - person Shalab; 22.11.2012
comment
@Shalab Насколько мне известно, вы не можете. Вам придется использовать лямбду с явными аргументами. - person sepp2k; 22.11.2012