2

Looking at code with foldl it is hard to understand its syntax, for example:

  def lstToMap(lst:List[(String,Int)], map: Map[String, Int] ):Map[String, Int] = {
    (map /: lst) (addToMap)
  }

Is /: infix operator? What does (map /: lst) mean, partial application? Why I can not call like this:

`/:  map lst addToMap`
Anton Ashanin
  • 1,817
  • 5
  • 30
  • 43

2 Answers2

5

Method names that end in a : character can be used on the left hand side of the instance they're bound to (ie, they associate to the right). In this case, /: is a method on List. As per the Scaladoc:

Note: /: is alternate syntax for foldLeft; z /: xs is the same as xs foldLeft z.

An alternative to what you wrote would be:

lst./:(map)(addToMap)

Edit: and another alternative with foldLeft:

lst.foldLeft(map)(addToMap)
Kristian Domagala
  • 3,686
  • 20
  • 22
  • Kristian, @DaoWen, As I understand `foldLeft` has two arguments - initial value and a folding function. Then why `lst.foldLeft(map, addToMap)` results in error `too many arguments for method foldLeft: (z: B)(f: (B, (String, Int)) => B)B` ? – Anton Ashanin Mar 25 '13 at 09:25
  • 1
    `foldLeft` has two parameter groups (as seen by the two groups of parens) - the first group expects one argument, which is the reason for the error message. The second argument goes in the second group. I've edited the answer with an example using `foldLeft`. As you can see, it's literally a drop-in replacement for `/:` – Kristian Domagala Mar 25 '13 at 09:52
  • Kristian, thanks! Where to read about Scala function parameter groups? Can't find this in the docs so far ... – Anton Ashanin Mar 25 '13 at 10:08
  • It's formally defined in section 4.6 of the Scala spec (http://www.scala-lang.org/docu/files/ScalaReference.pdf) and there's some more informal discussion in this question: http://stackoverflow.com/questions/6803211/whats-the-difference-between-multiple-parameters-lists-and-multiple-parameters – Kristian Domagala Mar 25 '13 at 23:39
2

Yes, /: can be used as an infix operator. However, the fold operation takes three arguments:

  1. The sequence to fold across
  2. The initial value for the reduction
  3. The function used for folding

Using infix you can only specify two of these three arguments: the sequence (which is the receiver) and the initial value. The fact that (map /: lst) is a partial application reflects the fact that you're still missing an argument. Here's an example of a product of a sequence of numbers, starting with an initial value of 1:

(1 /: xs)(_*_)

Since Scala supports curly braces for function literals, you can also use that to make the function argument look more like a function body:

(1 /: xs) { (x, y) =>
    x * y
}
DaoWen
  • 32,589
  • 6
  • 74
  • 101