I have the following code:
var x = Array(1,3,4,4,1,1,3)
var m = Int.MaxValue
x.foreach((x)=>(m = m min x))
I tried to simplify last sentence to:
x.foreach((m = _ min m))
But the interpreter says:
scala> x.foreach((m = _ min m))
<console>:8: error: missing parameter type for expanded function ((x$1) => x$1.min(m))
x.foreach((m = _ min m))
^
I tried to be more explicit about the type:
scala> x.foreach((m = (_:Int) min m))
<console>:8: error: type mismatch;
found : (Int) => Int
required: Int
x.foreach((m = (_:Int) min m))
^
The compiler and I don't understand each other :(
Best regards,
Stan
First, note that
val m = x.min
does what you want, as does
val m = (Int.MaxValue /: x)(_ min _)
I will leave it to you to read more about these things (the min method on collections, and folds; note that these are not quite as fast as what you wrote).
The problem is that the compiler is getting lost with what you mean and with what valid types might be when you write the underscore, and when you add the type information it thinks that you're trying to write a function right there and assign it to m. But of course m is an Int, not a function, so it complains.
Just write it explicitly. It's only a few extra characters:
x.foreach(i => m = m min i)
Related
In the various Lisps, it's possible for me to create a sequence of functions as if they'd just been normal values:
(def ops [+ - * /])
Which I can then iterate through, again, as if they were just normal values:
(doseq [op ops] // (doseq (op ops) is like for (op <- ops) in scala
(println (op 1 2 3 4)))
Now, I've tried a few things in Scala, all of them failing:
scala> List(+, -, *, /)
<console>:1: error: illegal start of simple expression
List(+, -, *, /)
^
scala> List[Double => Double](+, -, *, /)
<console>:1: error: illegal start of simple expression
List[Double => Double](+, -, *, /)
^
scala> List[Double => Double](+_, -_, *_, /_)
<console>:8: error: not found: value *
List[Double => Double](+_, -_, *_, /_)
^
<console>:8: error: not found: value /
List[Double => Double](+_, -_, *_, /_)
^
So what's the correct procedure of defining a list of functions/operators in Scala?
The problem is that these functions are binary operators, i.e., they take two operands and return one. So you have to use:
List[(Double, Double) => Double](_ + _, _ - _, _ * _, _ / _)
In Scala, most value-level operators are actually unary instance methods (maybe all are, not sure if there are counterexmaples). So when you talk about, say, addition of two values of type Double, you're really referring to a method of the first value that takes the second value as a parameter. The familiar infix operator syntax is just sugar. In other words,
scala> 5.7 + 6.3
res0: Double = 12.0
is really just a nice shorthand for:
scala> 5.7.+(6.3)
res1: Double = 12.0
As #bluenote10 already mentioned, you can capture these operators by creating anonymous function that take both the first instance and its operand as parameters and returns the result of the + method:
scala> (lhs: Double, rhs: Double) => lhs + rhs
res2: (Double, Double) => Double = <function2>
Or as in #bluenote10's example, if the type can be inferred (like in a list with the type provided), you can use the nice underscore syntax:
scala> val doublePlus: (Double, Double) => Double = _ + _
doublePlus: (Double, Double) => Double = <function2>
I want to iterate over a list of values using a beautiful one-liner in Scala.
For example, this one works well:
scala> val x = List(1,2,3,4)
x: List[Int] = List(1, 2, 3, 4)
scala> x foreach println
1
2
3
4
But if I use the placeholder _, it gives me an error:
scala> x foreach println(_ + 1)
<console>:6: error: missing parameter type for expanded function ((x$1) =>x$1.$plus(1))
x foreach println(_ + 1)
^
Why is that? Can't compiler infer type here?
This:
x foreach println(_ + 1)
is equivalent to this:
x.foreach(println(x$1 => x$1 + 1))
There's no indication as to what might be the type of x$1, and, to be honest, it doesn't make any sense to print a function.
You obviously (to me) meant to print x$0 + 1, where x$0 would the the parameter passed by foreach, instead. But, let's consider this... foreach takes, as a parameter, a Function1[T, Unit], where T is the type parameter of the list. What you are passing to foreach instead is println(_ + 1), which is an expression that returns Unit.
If you wrote, instead x foreach println, you'd be passing a completely different thing. You'd be passing the function(*) println, which takes Any and returns Unit, fitting, therefore, the requirements of foreach.
This gets slightly confused because of the rules of expansion of _. It expands to the innermost expression delimiter (parenthesis or curly braces), except if they are in place of a parameter, in which case it means a different thing: partial function application.
To explain this better, look at these examples:
def f(a: Int, b: Int, c: Int) = a + b + c
val g: Int => Int = f(_, 2, 3) // Partial function application
g(1)
Here, we applies the second and third arguments to f, and returned a function requiring just the remaining argument. Note that it only worked as is because I indicated the type of g, otherwise I'd have to indicate the type of the argument I was not applying. Let's continue:
val h: Int => Int = _ + 1 // Anonymous function, expands to (x$1: Int => x$1 + 1)
val i: Int => Int = (_ + 1) // Same thing, because the parenthesis are dropped here
val j: Int => Int = 1 + (_ + 1) // doesn't work, because it expands to 1 + (x$1 => x$1 + 1), so it misses the type of `x$1`
val k: Int => Int = 1 + ((_: Int) + 1) // doesn't work, because it expands to 1 + (x$1: Int => x$1 + 1), so you are adding a function to an `Int`, but this operation doesn't exist
Let discuss k in more detail, because this is a very important point. Recall that g is a function Int => Int, right? So, if I were to type 1 + g, would that make any sense? That's what was done in k.
What confuses people is that what they really wanted was:
val j: Int => Int = x$1 => 1 + (x$1 + 1)
In other words, they want the x$1 replacing _ to jump to outside the parenthesis, and to the proper place. The problem here is that, while it may seem obvious to them what the proper place is, it is not obvious to the compiler. Consider this example, for instance:
def findKeywords(keywords: List[String], sentence: List[String]) = sentence.filter(keywords contains _.map(_.toLowerCase))
Now, if we were to expand this to outside the parenthesis, we would get this:
def findKeywords(keywords: List[String], sentence: List[String]) = (x$1, x$2) => sentence.filter(keywords contains x$1.map(x$2.toLowerCase))
Which is definitely not what we want. In fact, if the _ did not get bounded by the innermost expression delimiter, one could never use _ with nested map, flatMap, filter and foreach.
Now, back to the confusion between anonymous function and partial application, look here:
List(1,2,3,4) foreach println(_) // doesn't work
List(1,2,3,4) foreach (println(_)) // works
List(1,2,3,4) foreach (println(_ + 1)) // doesn't work
The first line doesn't work because of how operation notation works. Scala just sees that println returns Unit, which is not what foreachexpects.
The second line works because the parenthesis let Scala evaluate println(_) as a whole. It is a partial function application, so it returns Any => Unit, which is acceptable.
The third line doesn't work because _ + 1 is anonymous function, which you are passing as a parameter to println. You are not making println part of an anonymous function, which is what you wanted.
Finally, what few people expect:
List(1,2,3,4) foreach (Console println _ + 1)
This works. Why it does is left as an exercise to the reader. :-)
(*) Actually, println is a method. When you write x foreach println, you are not passing a method, because methods can't be passed. Instead, Scala creates a closure and passes it. It expands like this:
x.foreach(new Function1[Any,Unit] { def apply(x$1: Any): Unit = Console.println(x$1) })
The underscore is a bit tricky. According to the spec, the phrase:
_ + 1
is equivalent to
x => x + 1
Trying
x foreach println (y => y + 1)
yields:
<console>:6: error: missing parameter type
x foreach println (y => y + 1)
If you add some types in:
x foreach( println((y:Int) => y + 1))
<console>:6: error: type mismatch;
found : Unit
required: (Int) => Unit
x foreach( println((y:Int) => y + 1))
The problem is that you are passing an anonymous function to println and it's not able to deal with it. What you really want to do (if you are trying to print the successor to each item in the list) is:
x map (_+1) foreach println
scala> for(x <- List(1,2,3,4)) println(x + 1)
2
3
4
5
There is a strange limitation in Scala for the nesting depth of expressions with underscore. It's well seen on the following example:
scala> List(1) map(1+_)
res3: List[Int] = List(2)
scala> Some(1) map (1+(1+_))
<console>:5: error: missing parameter type for expanded function ((x$1) => 1.+(x$1))
Some(1) map (1+(1+_))
^
Looks like a bug for me.
Welcome to Scala version 2.8.0.Beta1-prerelease (Java HotSpot(TM) Client VM, Java 1.6.0_17).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val l1 = List(1, 2, 3)
l1: List[Int] = List(1, 2, 3)
scala>
scala> l1.foreach(println(_))
1
2
3
How can I map over a List from 1 to 100 (inclusively) to make each item a Function1 that curries each element to partially apply (itself * _).
I tried this:
scala> val xs: List[Integer => Integer] = List.range(1,101).map { x => _ * x }
<console>:13: error: missing parameter type for expanded function ((x$1) =>
x$1.$times(x))
val xs: List[Integer => Integer] = List.range(1,101).map { x => _ * x }
Desired output:
val xs: List[Integer] = List[1,2,3,4, .., 100]
val desired: List[Integer => Integer] = List[(*1), (*2), ...]
Then, this would be expected too:
desired.get(0).apply(2) = 2 // 1 * 2
The compiler is telling you exactly what you need to fix here: "Missing parameter type". Change _ * x to (_: Integer) * x.
Incidentally, is there some reason you're using java.lang.Integer here? You probably mean scala.Int:
val fns: List[Int => Int] =
List.range(1, 101).map{x => (_: Int) * x}
Explanation:
The compiler can't infer the type of ''_''.
That is because there is no need for ''_'' to be a Integer, just because you used a List of Integers to create these functions.
With other words at this point it is not clear what kind of type should be bound to the free parameter of the partially applied function.
As stated before, this solution works for your case if the input will be Integers
(1 to 101) map ( x => x * (_:Int) )
An example:
val functions = (1 to 101) map ( x => x * (_:Int) )
This will work
functions map (_(2))
res13: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4 ...
This would fail:
functions map (_(2.5))
<console>:9: error: type mismatch;
found : Double(2.5)
required: Int
functions map (_(2.5))
I'm new to scala and trying to write a function literal that check whether a given integer is odd or not.
my first attempt is:
val isOdd = (x:Int) => (x & 1) == 1
it works great, and, since the parameter x only appears once within this function literal, I'm tempted to use the "_" notation to simplify it further, like this:
val isOdd = ((_:Int) & 1 ) == 1
however this time the compiler complains :
warning: comparing a fresh object using `==' will always yield false
val isOdd = ((_:Int) & 1 ) == 1
what does this warning mean? why does the compiler recognize ((_ :Int) & 1) as fresh object rather than a bitwise operation that results in a value? is there any way to write this function literal using the "_" notation?
The problem is basically that Scala needs to tell the difference between
val isOdd = ((_:Int) & 1 ) == 1
where you want everything to the right of the equals sign to be a lambda, and
val result = collection.map( _ + 1 )
where you want only the stuff inside the parentheses to be a lambda
Scala has decided that when you use the underscore to create a lambda, that it's going to pick the innermost set of parentheses as the boundaries of that lambda. There's one exception: (_:Int) doesn't count as the innermost parentheses because its purpose is only to group they type declaration with the _ placeholder.
Hence:
val isOdd = ((_:Int) & 1 ) == 1
^^^^^^^^^^^^^^
this is the lambda
val result = collection.map( _ + 1 )
^^^^^^^
this is the lambda
val result = collection.map(( _ + 1) / 2)
^^^^^^^^
this is the lambda
and the compiler can't infer the type of the _
val result = somemap.map(( _ + 1) / 2 * _)
^^^^^^^^
this is an inner lambda with one parameter
and the compiler can't infer the type of the _
^^^^^^^^^^^^^^^^^
this is an outer lambda with one parameter
This last case lets you do things like
_.map(_ + 1)
and have that get translated into
x => x.map( y=> y + 1 )
Only slightly cheating:
val isOdd = (_: Int) % 2 == 1
:-)
There you go:
val isOdd = ((_: Int) & 1) andThen (1 ==)
What Scala is doing is this:
it sees ((_:Int) & 1 ) and creates an object of type (Int) => Int, that is, a function.
it then applies the comparison operator == to compare this function to the value 1
A function is not equal to the value 1. Therefore the result is false, so your code is equivalent to:
val isOdd = false
What you could do is create another anonymous function that does the == 1 part of your computation. This is ugly:
val isOdd = ((_: Int) & 1)(_: Int) == 1
This is equivalent to the more verbose (and perhaps easier to understand):
val isOdd = (x: Int) => 1 == ((_: Int) & 1)(x)
A different approach
val isOdd = (_:Int).&(1) == 1
I had a List of Scala tuples like the following:
val l = List((1,2),(2,3),(3,4))
and I wanted to map it in a list of Int where each item is the sum of the Ints in a the corresponding tuple. I also didn't want to use to use the x._1 notation so I solved the problem with a pattern matching like this
def addTuple(t: (Int, Int)) : Int = t match {
case (first, second) => first + second
}
var r = l map addTuple
Doing that I obtained the list r: List[Int] = List(3, 5, 7) as expected. At this point, almost by accident, I discovered that I can achieve the same result with an abbreviated form like the following:
val r = l map {case(first, second) => first + second}
I cannot find any reference to this syntax in the documentation I have. Is that normal? Am I missing something trivial?
See Section 8.5 of the language reference, "Pattern Matching Anonymous Functions".
An anonymous function can be defined by a sequence of cases
{case p1 =>b1 ... case pn => bn }
which appear as an expression without a prior match. The expected type of such an expression must in part be defined. It must be either scala.Functionk[S1, ..., Sk, R] for some k > 0, or scala.PartialFunction[S1, R], where the argument type(s) S1, ..., Sk must be fully determined, but the result type R may be undetermined.
The expected type deternines whether this is translated to a FunctionN or PartialFunction.
scala> {case x => x}
<console>:6: error: missing parameter type for expanded function ((x0$1) => x0$1 match {
case (x # _) => x
})
{case x => x}
^
scala> {case x => x}: (Int => Int)
res1: (Int) => Int = <function1>
scala> {case x => x}: PartialFunction[Int, Int]
res2: PartialFunction[Int,Int] = <function1>
{case(first, second) => first + second} is treated as a PartialFunction literal. See examples in "Partial Functions" section here: http://programming-scala.labs.oreilly.com/ch08.html or section 15.7 of Programming in Scala.
Method map accepts a function. In your first example you create a function, assign it to a variable, and pass it to the map method. In the second example you pass your created function directly, omitting assigning it to a variable. You are doing just the same thing.