scala Functonal abstraction (List) not working - scala

please help me out in this scala throwing an error in below context
def SelectValues(list: List[Int],sel:Int => Boolean) ={
var sum =0
list.foreach{ e =>
if(sel(e)) sum += e
}
sum
println(sum)
}
println(SelectValues(List(1,2){e => true}))
enter image description here'screen shot

The problem is in your println line:
println(SelectValues(List(1,2){e => true}))
You don't have a comma between the List(1,2) and the {e => true} this means that you are sending a single parameter to SelectValues:
List(1,2){e => true}
This is equivalent to:
List(1,2)(f)
where f is the function. i.e. you are trying to call a function (apply in this case) on the resulting object from List(1,2) and not sending the second parameter (sel)).
the compiler analyzes first the SelectValues signature (before figuring out what your object is) and sees only one parameter.
To solve this, simply add the missing comma:
println(SelectValues(List(1,2), {e => true}))

Related

scala list.map returns list of empty

I'm trying to sum the values of the pairs that have the same character, but when printing, i get List((),())
here's my code
var lstA = List(("a",1),("b",2))
var lstB = List(("a",3), ("b",4))
val k = lstA.map(a => lstB.foreach(b => {
if(b._1 == a._1) (a._1, a._2+b._2) else a
}))
println(k)
of course there are better ways to do this, but I just want to know why this isn't working.
when debugging and evaluating the line if(b._1 == a._1) (a._1, a._2+b._2) else a i get the values of pairs as expected however when printing the list k is empty
The short and not entirely accurate answer is because foreach doesn't return anything. Actually, though, it does return something. Here is the signature:
def foreach[U](f: (A) ⇒ U): Unit
It returns a Unit type, which is used as a signal that the function has side-effects. From the documentation, the f parameter is:
the function that is applied for its side-effect to every element. The
result of function f is discarded.
So the function is expected to have a side effect. This could be something like println.

Map not applied correctly

In Scala, I have a method of type:
HashMap[String, String]
And this variable:
var bestMatch = new HashMap[String, (String, Int)]
At the end of the method, I am trying to return this value:
bestMatch.map((x, (y, count)) => (x, y))
However, I am getting the error:
Cannot resolve reference map with such signature
Why am I applying it incorrectly?
It should be something like this:
bestMatch.map(tuple => ( tuple._1, tuple._2._1))
You can't just put both arguments of the (String,Int) Tuple as your lambda function parameters. You need to use the tuple as one. If you write out your parameter types it becomes more clear maybe.
bestMatch.map((tuple: (String,(String,Int))) => ( tuple._1, tuple._2._1))
Also in your case it might be better to use mapValues since you're not doing anything with your key. Then you can use this:
bestMatch.mapValues(tuple => tuple._1)
Which is much more readable if you ask me. You could even go further and say:
bestMatch.mapValues(_._1)
You can write
bestMatch map {case (x, (y, count)) => (x, y)}

Convert Scala foreach to .map

I'm new to Scala and I'm trying to convert code of the form
val series: ListBuffer[Seq[Seq[Any]]] = ListBuffer[Seq[Seq[Any]]]()
points.foreach(point => {
if( conditionA )
series += doA(...) // returns a ListBuffer[Seq[Any]]
else
series += doB(...) // returns a ListBuffer[Seq[Any]]
})
to use .map(). I'm thinking its something like:
val series: ListBuffer[Seq[Seq[Any]]] = points.map(point => {
case conditionA => doA(...)
case _ => doB(...)
})
but this doesn't compile because (I believe) the mapped sequences get appended as a single Seq[Any] instead of Seq[Seq[Any]], so I get the error
Expression of type Seq[Any] doesn't conform to expected type ListBuffer[Seq[Seq[Any]]]
Any ideas? Is there something wrong with syntax?
Let me suppose a few things, you have some function def doA(arg1: A): ListBuffer[Seq[Any]] such that you ultimately want to arrive at a List[Seq[Any]] as the final result type after mapping this function over your collection. Then what you want is flatMap instead of map:
val series = points flatMap{
case point if conditionA(point) => doA(point) result ()
case point => doB(point) result ()
}
The reason I make such a supposition is that the only reason you'd ever want to use a ListBuffer[A] in the general form is to create a List[A] through some side-effecting expression. Hence, you ultimately want a List[Seq[A]] as your final output.

Yielding with For-loop and pass to match-case Expression

I was experimenting with the following code;
(for (f <- (new File(".")).listFiles() if !f.isDirectory) yield f) match {
case x:File => println(x.getAbsoluteFile)
case _ => println(_)
}
Obviously I am wrong somehow, as I am getting the following Error
scrutinee is incompatible with pattern type;
found : java.io.File
required: Array[java.io.File]
case x:File => println(x.getAbsoluteFile)
^
What I was trying to do is pretty obvious; I tried to get each yielded value from the for-loop and pass it to a match-case "filter". I am not interesting in writing a better File tree filter rather than knowing the reason of the Error that I am getting and if it is possible to fix it (or rewrite somehow else).
Cheers!
Just a few symbols away:
for (f <- (new File(".")).listFiles() if !f.isDirectory) f match {
case x:File => println(x.getAbsoluteFile)
case _ => println(_)
}
The diff is
yield f)
{ f
In your case you're first processing (listing|filtering|yielding one-by-one) whole collection and only then match whole result.

some operator questions

I'm new to scala so sorry if this is easy but I've had a hard time finding the answer.
I'm having a hard time understanding what <- does, and what ()=> Unit does. My understanding of these is that -> is sometimes used in foreach, and that => is used in maps. Trying to google "scala "<-" doesn't prove very fruitful. I found http://jim-mcbeath.blogspot.com/2008/12/scala-operator-cheat-sheet.html but it wasn't as helpful as it looks at first glance.
val numbers = List("one", "two", "three","four","five")
def operateOnList() {
for(number <- numbers) {
println(number + ": came out of this crazy thing!")
}
}
def tweener(method: () => Unit) {
method()
}
tweener(operateOnList)
() => Unit means that method is a function that takes no parameter and returns nothing (Unit).
<- is used in the for comprehension as an kind of assignation operator. for comprehension are a little bit specific because they are internally transformed. In your case, that would be transforms as numbers.foreach(i => println(i + ": came out of this crazy thing!"))
<- in the for comprehension means that we will iterate over each element of the numbers list and passed to number.
'<-' could be threated as 'in' so
for(number <- numbers){
...
}
could be translated into english as for each number in numbers do
'<-' has a twin with a different semantics: '->'. Simply it is just a replacement of comma in tuples: (a,b) is an equivalent to (a->b) or just a->b. The meaning after this symbols is that 'a' maps to 'b'. So this is often used in definition of Maps:
Map("a" -> 1,"aba" -> 3)
Map("London" -> "Britain", "Paris" -> "France")
Here you can think about mapping as a projection (or not) via some function (e.g. 'length of string', 'capital of').
Better explanation is here.
Last, but not least is '=>' which is map too, but with a general semantics. '=>' is in use all over the place in anonymous expressions:
scala> List(1,2,3,4).map(current => current+1)
res5: List[Int] = List(2, 3, 4, 5)
Which is for each element map current element of list with function 'plus one'
List(1,2,3,4).map(c => c%2 match {
| case 0 => "even"
| case 1 => "odd"
| }
| )
res6: List[java.lang.String] = List(odd, even, odd, even)
Map current element with provided pattern mathing
In the method
def tweener(method: () => Unit) {
method()
}
the method is called tweener, the parameter is arbitrarily named method, and the type of method is () => Unit, which is a function type, as you can tell from the =>.
Unit is a return type similar to void in Java, and represents no interesting value being returned. For instance, the return type of print is Unit. () represents an empty parameter list.
Confusingly, () is also used to represent an instance of Unit, called the unit value, the only value a Unit can take. But this is not what it means in the function type () => Unit, just as you can't have a function type 42 => Unit.
Back to your example, tweener takes a function of type () => Unit. operateOnList is a method, but it gets partially applied by the compiler to turn it into a function value. You can turn methods into functions yourself like this:
scala> def m = println("hi")
m: Unit
scala> m _
res17: () => Unit = <function0>
operateOnList can be turned into the right type of function because its parameter list is empty (), and its return type is implicity Unit.
As a side-note, if operateOnList were defined without the empty parameter list (as is legal, but more common when the return type is not Unit), you would need to manually partially apply it, else its value will be passed instead:
def f1() {}
def f2 {}
def g(f: () => Unit) {}
g(f1) // OK
g(f2) // error, since we're passing f2's result (),
// rather than partial function () => Unit
g(f2 _) // OK