Johan
Johan

Reputation: 23

function literals in scala for expression

Hi I am new to scala and have a question.

When I specify the non abbreviated version of a funtion literal in a for loop, scala does nothing with it.

e.g.

    val myList = List("one","two","tree","four","five")
    //compiles but does not print anything
   for (arg <- lst) (arg:String) => {println(arg)}

    //does print one, two, tree, four,five on separated lines
   lst.foreach((arg:String) => {println(arg)})

On the other hand the abbreviated version of the above function literal ( println(arg) ) in a for loop does seem to work as expected:

    val myList = List("one","two","tree","four","five")
    //does print one, two, tree, four,five on separated lines
    for (arg <- lst) println(arg)

Is this a bug or did I misunderstand something? thanks a lot

Upvotes: 2

Views: 84

Answers (2)

elm
elm

Reputation: 20405

More of a side note, consider this

val a = for (arg <- lst) (arg:String) => {println(arg)}
a: Unit = ()

where a of type Unit does nothing, and

val b = for (arg <- lst) yield (arg:String) => {println(arg)}
b: List[String => Unit] = List(<function1>, <function1>, <function1>, <function1>, <function1>)

where we tell the for comprehension to deliver a collection of functions from String onto Unit (due to the println). Then we can apply each entry in lst to each corresponding function in b for instance like this,

(lst zip b).foreach { case (s, f) => f(s) }
one
two
tree
four
five

Note that f(s) is a shorthand for f.apply(s).

Upvotes: 1

Jesper
Jesper

Reputation: 206766

It's not a bug in Scala. When you specify the function, like this:

for (arg <- lst) (arg:String) => {println(arg)}

then Scala is indeed not doing anything with it, because you only specified the function - you didn't tell Scala to actually call the function. Your for loop basically means: "for each element in lst, declare this function".

You'll have to specify that you want the function to be called:

for (arg <- lst) ((arg:String) => {println(arg)})(arg)

This reads as: "for each element in lst, declare this function and call it with arg".

Note the difference with foreach:

lst.foreach((arg:String) => {println(arg)})

This means: "call foreach on lst, and pass it this function" - foreach is then going to call the function for each element in lst.

Upvotes: 4

Related Questions