tags:

views:

136

answers:

2

I'm not sure why this doesn't work:

scala> case class Loader(n: String, x: String, l: List[String])
scala> val m: Map[String, (List[String])=>Loader] = 
     | Map("x" -> Loader("x", "x1", _:List[String]))              

<console>:8: error: type mismatch;
 found   : (List[String]) => (java.lang.String, Loader)
 required: (String, (List[String]) => Loader)
       Map("x" -> Loader("x", "x1", _:List[String]))

but this does?

scala> Loader("t", "x", _:List[String])
res7: (List[String]) => Loader = function1>

scala> val m = Map("x" -> res7)
m: scala.collection.immutable.Map[java.lang.String,(List[String]) => Loader] =
  Map((String,function1>))
+4  A: 

The parser was not sure where to put the beginning of the anonymous function. Sometimes you can solve this by adding another pair of parentheses (though not always):

val m: Map[String, (List[String])=>Loader] =
Map("x" -> (Loader("x", "x1", _:List[String])))

I don’t see any ambiguities here, so it might just not have been smart enough to figure it out. I think, the parser overlooked the possibility to have an anonymous function just after the -> (which also is a library construct and uses implicit magic and all the wicket stuff which makes the little parser’s mind loop).

When you write it as an explicit tuple, it’ll work fine.

val m: Map[String, (List[String])=>Loader] =
Map(("x", Loader("x", "x1", _:List[String])))
Debilski
Thx. Yeah I noticed the same thing... that it worked with Tuples.
Vonn
+5  A: 

One more victim of the overload of _ in Scala. Consider this:

f(_, 5) + 1 // Partial function application
f(_ + 1, 5) // Closure

In the first case, _ is replacing the entire parameter. In this case, it stands for a partial application of f. In practice, it's equivalent to x => f(x, 5) + 1, as the whole expression that contains f is turned into a closure.

In the second case, _ is part of an expression. In this case, the whole expression is turned into a closure, up to any expression delimiter -- by which I mean that if the expression is nested inside another, only the inner expression is turned into a closure. In practice, it is equivalent to f(x => x + 1, 5).

Daniel