Scala function inside a filter loop not working (type mismatch) - scala

I'm new in Scala, I have a function (that works)
object Utiles {
def func(param: String, param2: String): String = {
// Do Somthing
true
}
}
In a different file, I'm using this function successfully, but when i insert it to a filter it gives me an error
list.filter(value => {
Utiles.func(value.param ,value.param2)
})
the error I'm getting is:
type mismatch;
found : String
required: None.type
Utiles.func(value.param ,value.param2)
Any idea what i'm doing wrong?

You have three issues here (that I can see as the question is currently written):
Your func function doesn't compile. You have put the return type of the function as String, yet you are returning a Boolean (true). Either change the return type, or end the function by returning a String.
.filter(...) requires you to make something either true or false. This will be fixed if you change the return type of func to be Boolean. If your return type is supposed to be String, you'll need to compare that String to something. Eg:
List("foo", "bar").filter(x => func(x) == "baz")
Your type mismatch error is because you seem to be passing a String into your func function where it is expecting a None.type (for some reason).
What I'm getting at, is you have failed to give us a Minimal, Complete, and Verifiable example. I have debugged your code as you have presented it, but I have a strong feeling that you have tried to cut down your real function to a point where your errors (and the function itself) make no sense.

If you noticed filter takes a predicate
def filter(p: A => Boolean): List[A]
which means your filter function on List[SomeData] should be SomeData => Boolean.
example:
scala> def fun(param1: String, param2: String): Boolean = param1 == param2
fun: (param1: String, param2: String)Boolean
scala> List("updupd", "whatwhat").filter(p => fun(p, "updupd"))
res0: List[String] = List(updupd)

I'm not sure how you're able to use func in a different place because the return type is wrong. It should be Boolean:
object Utiles {
def func(param: String, param2: String): Boolean = {
// Do Somthing
true
}
}

Related

Scala - type mismatch problem with own type (String) and Future

I have a method, which need String type as an argument:
type Identity = String
case class RequireSmth(param: Identity) extends Something
Now I call this method in more complex order:
createMe(as[List])(arg =>{ parse(RequireSmth(getAction(name, surname).map(bool => getData(surname, bool).id))) })
Parse looks like:
def parse(ob: Something)
Where:
def getAction(name: String, surname: String): Future[Boolean] = {
someObject.get(name).map(_.getSomething(surname).isPossibleToTake.getOrElse(false)) //someObject is defined in constructor and does not matter here
}
def getData: (String, Boolean) => MyObject = {
case ("Doe", true) => possible
case _ => notPossible
}
MyObject, possible and notPossible definition:
case class MyObject(id : String, name: String, surname: String)
val possible = MyObject( id = "ok", name ="John", surname = "Doe")
val notPossible = MyObject( id = "not ok", name ="John", surname = "Doe")
The problem is, when I call RequireSmth method I got an error:
type mismatch;
found: scala.concurrent.Future[String]
required: com.my.smth.Identity (which expands to) String
How can I solve this problem to return Identity (or String) instead of Future[String]?
Keep the information inside the Future like this:
getAction(name, surname).map(bool => getData(surname, bool).id).map(RequireSmth)
Just keep chaining the operations together, keeping everything inside the Future:
getAction(name, surname)
.map(bool => getData(surname, bool).id)
.map(RequireSmth) // Or x => RequireSmth(x) if necessary
.map(parse)
At some point you will get to a method that has a side-effect and returns Unit, and that will be executed when all the actions in the Future are complete.
In the unlikely event that you actually need to get the value out of the Future, use Await.result. But in most cases this will not be necessary.
You need to flip the method calls:
val res: Future[???] =
getAction(name, surname)
.map(bool => getData(surname, bool).id)
.map(RequireSmth)
.map(parse)
Note that Future[String] is not a String, it's a computation that will yield a value in the future, and that means that the entire computation stack needs to return a Future[T] as well (unless you explicitly await, which blocks and is not recommended).

Why am I getting a type-mismatch error, here?

I am unable to understand why the below code gives type mismatch error -
Here I am using generics and at line 11 it is giving type mismatch error. Shouldn't it interpret T as Int.
object FunctionParamGeneric {
def main(args: Array[String]) : Unit= {
exec[Int](Fun[Int])
}
def exec[T]( f:() => T) : T = {
println("Inside exec")
f()
}
def Fun[T]() : T = {
println("Inside Fun with key ")
123
}
}
However, if I do
object FunctionParamGeneric {
def main (args: Array[String]) : Unit= {
exec[Int](() => 1)
}
def exec[T]( f:() => T) : T = {
println("Inside exec")
f()
}
}
It works fine. Because f is inferred to be called with an Int in the second snippet, I would expect the same to happen in the in first code snippet, but that's not the case. Why not?
First snippet:
You get error because you have specified generic return type for Fun while you are returning Int.
Suppose if this expression was allowed, now consider these two statements:
Fun[Int]() // would have returned 123
Fun[String]() // what would be output?
The first statement would have returned 123 without any problem but what would be the output in second case?
That's why such expressions are not allowed.
Second snippet:
In second snippet it works because when you use exec[Int](() => 1), you are passing a literal function as argument while in first snippet you giving definition of Fun.
To explain it further, if you look at the definition of exec:
def exec[T]( f:() => T) : T
It takes a Function0 function (which can return any type) as parameter. So when you call exec[Int](() => 1), you are passing function () => 1 which returns Int (Note that this is not a generic function). Hence it works.
While in the first snippet, you were defining a generic function Fun with generic return type. But from the body of the function you were returning Int value.
Your problem lies here:
def Fun[T]() : T = {
println("Inside Fun with key ")
123
}
You're implicitly returning 123. Which isn't of type T, but of type Int. So the compiler generates an error.
If you want Fun to always return an Int you can do that, by defining it as Fun(): Int = ....
Then you should be able to call
exec[Int](Fun)

Spark Key/Value filter Function

I have data in a Key Value pairing. I am trying to apply a filter function to the data that looks like:
def filterNum(x: Int) : Boolean = {
if (decimalArr.contains(x)) return true
else return false
}
My Spark code that has:
val numRDD = columnRDD.filter(x => filterNum(x(0)))
but that wont work and when I send in the:
val numRDD = columnRDD.filter(x => filterNum(x))
I get the error:
<console>:23: error: type mismatch;
found : (Int, String)
required: Int
val numRDD = columnRDD.filter(x => filterNum(x))
I also have tried to do other things like changing the inputs to the function
This is because RDD.filter is passing in the Key-Value Tuple, (Int, String), and filterNum is expecting an Int, which is why the first attempt works: tuple(index) pulls out the value at that index of the tuple.
You could change your filter function to be
def filterNum(x: (Int, String)) : Boolean = {
if (decimalArr.contains(x._1)) return true
else return false
}
Although, I would personally do a more terse version as the false is baked into the contains and you can just use the expression directly:
columnRDD.filter(decimalArr.contains(_._1))
Or, if you don't like the underscore syntax:
columnRDD.filter(x=>decimalArr.contains(x._1))
Also, do not use return in scala, the last evaluated line is the return automatically

In Scala, can you make an anonymous function have a default argument?

This works:
scala> def test(name: String = "joe"): Boolean = true
test: (name: String)Boolean
I expected this to work in the same way:
scala> val test: String => Boolean = { (name: String = "joe") => true }
console>:1: error: ')' expected but '=' found.
The boring, correct answer is no, you can't, but actually you kind of can, with the experimental single abstract method (SAM) synthesis in 2.11.
First you need to define your own SAM type with the default value for the apply method's parameter:
trait Func {
def apply(name: String = "joe"): Boolean
}
Now you can use the function literal notation to define a Func (note that you'll need to have started the REPL with -Xexperimental for this step to work):
val f: Func = { (name: String) => name == "joe" }
Or just:
val f: Func = _ == "joe"
And then the usual stuff:
scala> f("joe")
res0: Boolean = true
scala> f("eoj")
res1: Boolean = false
And the punchline:
scala> f()
res2: Boolean = true
It's not exactly the syntax you're asking for, and there are no promises that this will ever leave experimental status, and even if it does, default arguments may not be supported—but I still think it's pretty neat that it works now.
To expand on "The boring, correct answer is no" in Travis Brown's answer:
Functions (i.e. objects of FunctionN[...] type) can't have default arguments in Scala, only methods can. Since anonymous function expressions produce functions (and not methods), they can't have default arguments.
This is bit dirty solution I think, using currying
def testDef(nameDef: String)(name2: String): Boolean = {
val name3 = if ( name2 != "") name2 else nameDef
//use name3 for your logic
true
}
//> testDef: (name: String)(name2: String)Boolean
Curry the testDef method to hold default value as shown below.
var test = test("joe")_ //> test : String => Boolean=function1
test("fun") //"fun" will be used as name3
test("") // "joe" will be used as name3

How to check to see if a string is a decimal number in Scala

I'm still fairly new to Scala, and I'm discovering new and interesting ways for doing things on an almost daily basis, but they're not always sensible, and sometimes already exist within the language as a construct and I just don't know about them. So, with that preamble, I'm checking to see if a given string is comprised entirely of digits, so I'm doing:
def isAllDigits(x: String) = x.map(Character.isDigit(_)).reduce(_&&_)
is this sensible or just needlessly silly? It there a better way? Is it better just to call x.toInt and catch the exception, or is that less idiomatic? Is there a performance benefit/drawback to either?
Try this:
def isAllDigits(x: String) = x forall Character.isDigit
forall takes a function (in this case Character.isDigit) that takes an argument that is of the type of the elements of the collection and returns a Boolean; it returns true if the function returns true for all elements in the collection, and false otherwise.
Do you want to know if the string is an integer? Then .toInt it and catch the exception. Do you instead want to know if the string is all digits? Then ask one of:
s.forall(_.isDigit)
s matches """\d+"""
You also may consider something like this:
import scala.util.control.Exception.allCatch
def isLongNumber(s: String): Boolean = (allCatch opt s.toLong).isDefined
// or
def isDoubleNumber(s: String): Boolean = (allCatch opt s.toDouble).isDefined
You could simply use a regex for this.
val onlyDigitsRegex = "^\\d+$".r
def isAllDigits(x: String) = x match {
case onlyDigitsRegex() => true
case _ => false
}
Or simply
def isAllDigits(x: String) = x.matches("^\\d+$")
And to improve this a little bit, you can use the pimp my library pattern to make it a method on your string:
implicit def AllDigits(x: String) = new { def isAllDigits = x.matches("^\\d+$") }
"12345".isAllDigits // => true
"12345foobar".isAllDigits // => false
Starting Scala 2.13 we can use String::toDoubleOption, to determine whether a String is a decimal number or not:
"324.56".toDoubleOption.isDefined // true
"4.06e3".toDoubleOption.isDefined // true
"9w01.1".toDoubleOption.isDefined // false
Similar option to determine if a String is a simple Int:
"324".toIntOption.isDefined // true
"Ă 32".toIntOption.isDefined // false
"024".toIntOption.isDefined // true
import scala.util.Try
object NumCruncher {
def isShort(aString: String): Boolean = Try(aString.toLong).isSuccess
def isInt(aString: String): Boolean = Try(aString.toInt).isSuccess
def isLong(aString: String): Boolean = Try(aString.toLong).isSuccess
def isDouble(aString: String): Boolean = Try(aString.toDouble).isSuccess
def isFloat(aString: String): Boolean = Try(aString.toFloat).isSuccess
/**
*
* #param x the string to check
* #return true if the parameter passed is a Java primitive number
*/
def isNumber(x: String): Boolean = {
List(isShort(x), isInt(x), isLong(x), isDouble(x), isFloat(x))
.foldLeft(false)(_ || _)
}
}
Try might not performance-wise be the optimal choice, but otherwise it's neat:
scala> import scala.util.Try
scala> Try{ "123x".toInt }
res4: scala.util.Try[Int] = Failure(java.lang.NumberFormatException: For input string: "123x")
scala> Try{ "123x".toInt }.isSuccess
res5: Boolean = false
#Jesper's answer is spot on.
Do NOT do what I'm suggesting below (explanation follows)
Since you are checking if a given string is numeric (title states you want a decimal), the assumption is that you intend to make a conversion if the forall guard passes.
A simple implicit in scope will save a whopping 9 key strokes ;-)
implicit def str2Double(x: String) = x.toDouble
Why this is dangerous
def takesDouble(x: Double) = x
The compiler will now allow takesDouble("runtime fail") since the implicit tries to convert whatever string you use to Double, with zero guarantee of success, yikes.
implicit conversions then seem better suited to situations where an acceptable default value is supplied on conversion failure (which is not always the case; therefore implicit with caution)
Here is one more:
import scala.util.Try
val doubleConverter: (String => Try[Double]) = (s: String) => Try{ s.map(c => if ((Character.isDigit(c) == true) || (c == '.')) Some(c) else None).flatten.mkString.toDouble }
val d1: Try[Double] = doubleConverter("+ 1234.0%")
val d2: Try[Double] = doubleConverter("+ 1234..0%")
Based on brilliant Jexter's solution, in this piece of code I take care of the NullPointerException using Option:
def isValidPositiveNumber(baseString: Option[String]): Boolean = baseString match {
case Some(code) => !code.isEmpty && (code forall Character.isDigit)
case None => false
}