def checkHappynumber(n: Int): Boolean = {
val set = scala.collection.mutable.HashSet[Int]()
var num: Int = n
while(num != 1) {
var newnum: Int = 0
while (num != 0) {
newnum += (num % 10) * (num % 10)
num /= 10
}
if(!set.add(newnum)){
return false;
}
num = newnum
}
return true
}
What's "!" role in there? the if(!set.add(newnum))? I know that hashset can't have repeated value. The only question is how "!" works here.
In Scala, !foo is syntactic sugar for foo.unary_!. In other words, !foo is just calling the method named unary_! just like foo.bar is calling the method bar. There is nothing special about unary_! in that regard.
In your case, this means that !set.add(newnum) is just syntactic sugar for set.add(newnum).unary_!.
Like with all other methods, if you want to know what the method does, you first need to find where it is defined. In this case, the return type of scala.collection.mutable.Set.add is scala.Boolean which means the specific method being called is scala.Boolean.unary_!, which is defined like this:
def unary_!: Boolean
Negates a Boolean expression.
!a results in false if and only if a evaluates to true and
!a results in true if and only if a evaluates to false.
Returns: the negated expression
! is a negation operator (!true is false, !false is true). HashSet.add returns true if element was not present in the set (successfully added), false otherwise. This code returns false if element was already present in the hashset (trying to add it for the second time).
Here's documentation of add method.
Related
If I call this with 3 I get back an Int-typed return as I expect.
def determineKind( a:Int ):Any = {
if( a < 5 )
a.toInt
else if(a<50)
a.toLong
else if(a<100)
a.toFloat
else
a.toDouble
}
If I call this with 3, I get back a Double.
def determineKind2( a:Int ):Any = {
val aResult = { if( a < 5 )
a.toInt // Execution flows here
else if(a<50)
a.toLong
else if(a<100)
a.toFloat
else
println("Oops!") // Never executed--yet I get a Double back!
a.toDouble
}
aResult
}
Why? I don't want the Double. (The real function uses a match/case block, which also seems to convert any of these numerical types to Double.)
Something about wrapping things in a code block triggers the unwanted type change to Double.
Why is that?
You problem lies in how you defined the if block, effectively, in determineKind2, a.toDouble is always assigned to aResult and the entire result of the if block is discarded.
The illustration of what is happening:
def block = {
if(condition)
v1
else
println(v2)
v2
}
Always returns v2. This happens because the same code using explicit curly braces would be this:
def block = {
if(condition) {
v1
} else {
println(v2)
}
v2
}
Notice how v2 is outside the if block. In case statement block on the other hand:
condition match {
case true => v1
case _ =>
println(v2)
v2
}
The same doesn't happen above, the blocks in cases are ended by the start of another case in the same scope depth.
As a side note: indentation doesn't have any effect in how blocks are compiled.
This is a tricky situation where numeric widening comes into play. In the first example, you are stating the return type, Any, and thus there is no need to widen any of the types. In the second case, val aResult = you are asking Scala to infer the type of the if-expression, and it will avoid to infer Any and instead decide to widening the individual types numerically to a Double. Often this widening is what you'd want, e.g. say you write Seq(1, 2.3, 4.5) - you'd expect that to be a Seq[Double] and not Seq[Any].
If you define the type of aResult, you ask Scala to accept the unspecific type of Any:
def determineKind(a: Int): Any = {
val res: Any /* ! */ = if (a < 5)
a.toInt
else if (a < 50)
a.toLong
else if(a < 100)
a.toFloat
else
a.toDouble
res
}
assert(determineKind(3).isInstanceOf[Int])
Numeric widening appears in section 6.26.1 of the Scala Language Specification:
If e has a primitive number type which weakly conforms to the expected type, it is widened to the expected type using one of the numeric conversion methods toShort, toChar, toInt, toLong, toFloat, toDouble defined here.
Greg, this block below returns value of type Double because the last thing you do in it is calling toDouble method on a.
val aResult = {
if( a < 5 )
a.toInt // Execution flows here
else if(a<50)
a.toLong
else if(a<100)
a.toFloat
else
println("Oops!") // Never executed--yet I get a Double back!
a.toDouble // <---- this line is not a part of if else expression
}
That's a good reason why to use curly braces, so you can prevent mistakes like this.
I have a string, lets say val mystr = "abcde", and I want to find the minimal substring of mystr which satisfies a given condition. I have to send a string to an external system, so the only way to do this is to iterate through the length of the string and make requests to the external system, and break when the response from the external system returns true
eg.
callExtSystemWith("a") //Returns false
callExtSystemWith("ab") //Returns false
callExtSystemWith("abc") //Returns true
Then my method should return "abc". I read that breaks are not the scala way, so was wondering what is the scala way of achieving this?
Right now I have:
for {end <- 1 to mystr.length)}{
callExtSystemWith(mystr.substring(0,end))
// I Want to break when this is true.
}
Help much appreciated
You can use inits.toStream.reverse.drop(1) (1 to s.length).map(s.take).toStream to create a lazy stream with a, ab, abc, abcd.
Then filter those strings, so that only the ones for which callExtSystemWith returns true are left.
Then get the first string for which callExtSystemWith returns true. Because this is a lazy stream, no unecessary requests will be made to the server once the first match is found.
val s = "abcdefgh"
val strs = (1 to s.length).map(s.take).toStream
strs.filter(callExtSystemWith).headOption match {
case Some(s) => "found"
case _ => "not found"
}
You can also use find instead of filter + headOption
Quite often break can be replaced with find on some sequence
So here is another short solution for this problem:
def findSuitablePrefix(mystr: String): Option[String] =
(1 to mystr.length).view.map(mystr.substring(0, _)).find(callExtSystemWith)
.view makes the evaluation lazy to avoid creating extra substrings.
.map transforms the sequence of indexes into a sequence of substrings.
And .find "breaks" after the first element for which callExtSystemWith returns true is found.
In Scala there are no normal breaks but there are other solutions. The one I like better is to create a function and force a return (instead of a normal break). Something like:
def callAndBreak(mystr:String) : Int = {
for (end <- 1 to mystr.length) {
if ( callExtSystemWith(mystr.substring(0,end)) ) return end
}
end
}
Here I return end but you can return anything
If you want to avoid using return or breaks, you could also use foldLeft:
val finalResult = (1 to mystr.length).foldLeft(false) { (result, end) =>
if(!result) callExtSystemWith(mystr.substring(0, end)) else result
}
However, it is a bit hard to read, and will walk the entire length of the string.
Simple recursion might be a better way:
def go(s: String, end: Int): Boolean = {
if(end >= s.length) false
else {
callExtSystemWith(s.substring(0, end)) || go(s, end + 1)
}
}
go(mystr, 1)
How is the equals function defined for a 'function' type:
val javaVersion = () => sys.props("java.version")
val anonfun0 = new Function0[String] {
def apply(): String = sys.props("java.version")
}
assert(javaVersion() == anonfun0()) // This works!
It works because you're comparing the result and not the functions. Remove the () and it should return false.
Your assertion is not testing the equality of the functions , but the value they return.
Note the difference between:
assert(javaVersion() == anonfun0()) // equality of return values
and:
assert(javaVersion == anonfun0) // equality of vals
Your assertion returns true because both functions return the result of sys.props("java.version").
I know this is very trivial to do with a simple case check, but it seems it should be possible to write a method that does something like the following, that is generalizes to all numeric types:
def checkNonZero(t: Long, field: String): List[String] = {
if (t == 0) println("was zero") else println("wasn't zero")
}
What's the best way to do this?
This can be done with the Number type.
def checkNonZero(n: Number) = n != 0
Or you can use the Numeric typeclass.
def checkNonZero[T : Numeric](n: T) = {
val num = implicitly[Numeric[T]]
!num.equiv(n, num.zero)
}
EDIT
Actually, you can just write it like this:
def checkNonZero[T : Numeric](n: T) = n != 0
Unless you define new custom instances of Numeric of course.
An alternative way to Jasper-M's second solution goes as follows:
def isNotZero[A](n: A)(implicit num: Numeric[A]) = !num.equiv(n, num.zero)
This saves the line val num = implicitly[Numeric[A]], while still allowing you to work with num if you so desire.
Despite this method actually taking 2 parameters, because the second one's implicit, you can use it like you would any other non-curried single-parameter method:
isNotZero(3) // true
isNotZero(0.1) // true
isNotZero(0) // false
isNotZero(0.0) // false
I am a newbie scala programmer and came across a weird behavior.
def balanceMain(elem: List[Char]): Boolean =
{
if (elem.isEmpty)
if (count == 0)
true;
else false;
if (elem.head == '(')
balanceMain(elem.tail, open, count + 1);....
Above basically I want to return true if elem.isEmpty and count == 0. Otherwise, I want to return false.
Now above I have read that there is no need to add a return statement in scala. So I have omitted return above. But it doesn't return the boolean. If I add a return statement as return true. it works perfectly. Why is it so?
Also, why is it considered a bad practice to have return statements in scala
It's not as simple as just omitting the return keyword. In Scala, if there is no return then the last expression is taken to be the return value. So, if the last expression is what you want to return, then you can omit the return keyword. But if what you want to return is not the last expression, then Scala will not know that you wanted to return it.
An example:
def f() = {
if (something)
"A"
else
"B"
}
Here the last expression of the function f is an if/else expression that evaluates to a String. Since there is no explicit return marked, Scala will infer that you wanted to return the result of this if/else expression: a String.
Now, if we add something after the if/else expression:
def f() = {
if (something)
"A"
else
"B"
if (somethingElse)
1
else
2
}
Now the last expression is an if/else expression that evaluates to an Int. So the return type of f will be Int. If we really wanted it to return the String, then we're in trouble because Scala has no idea that that's what we intended. Thus, we have to fix it by either storing the String to a variable and returning it after the second if/else expression, or by changing the order so that the String part happens last.
Finally, we can avoid the return keyword even with a nested if-else expression like yours:
def f() = {
if(somethingFirst) {
if (something) // Last expression of `if` returns a String
"A"
else
"B"
}
else {
if (somethingElse)
1
else
2
"C" // Last expression of `else` returns a String
}
}
This topic is actually a little more complicated as described in the answers so far. This blogpost by Rob Norris explains it in more detail and gives examples on when using return will actually break your code (or at least have non-obvious effects).
At this point let me just quote the essence of the post. The most important statement is right in the beginning. Print this as a poster and put it to your wall :-)
The return keyword is not “optional” or “inferred”; it changes the
meaning of your program, and you should never use it.
It gives one example, where it actually breaks something, when you inline a function
// Inline add and addR
def sum(ns: Int*): Int = ns.foldLeft(0)((n, m) => n + m) // inlined add
scala> sum(33, 42, 99)
res2: Int = 174 // alright
def sumR(ns: Int*): Int = ns.foldLeft(0)((n, m) => return n + m) // inlined addR
scala> sumR(33, 42, 99)
res3: Int = 33 // um.
because
A return expression, when evaluated, abandons the current computation
and returns to the caller of the method in which return appears.
This is only one of the examples given in the linked post and it's the easiest to understand. There're more and I highly encourage you, to go there, read and understand.
When you come from imperative languages like Java, this might seem odd at first, but once you get used to this style it will make sense. Let me close with another quote:
If you find yourself in a situation where you think you want to return early, you need to re-think the way you have defined your computation.
I don't program Scala, but I use another language with implicit returns (Ruby). You have code after your if (elem.isEmpty) block -- the last line of code is what's returned, which is why you're not getting what you're expecting.
EDIT: Here's a simpler way to write your function too. Just use the boolean value of isEmpty and count to return true or false automatically:
def balanceMain(elem: List[Char]): Boolean =
{
elem.isEmpty && count == 0
}
By default the last expression of a function will be returned.
In your example there is another expression after the point, where you want your return value.
If you want to return anything prior to your last expression, you still have to use return.
You could modify your example like this, to return a Boolean from the first part
def balanceMain(elem: List[Char]): Boolean = {
if (elem.isEmpty) {
// == is a Boolean resulting function as well, so your can write it this way
count == 0
} else {
// keep the rest in this block, the last value will be returned as well
if (elem.head == "(") {
balanceMain(elem.tail, open, count + 1)
}
// some more statements
...
// just don't forget your Boolean in the end
someBoolExpression
}
}
Don't write if statements without a corresponding else. Once you add the else to your fragment you'll see that your true and false are in fact the last expressions of the function.
def balanceMain(elem: List[Char]): Boolean =
{
if (elem.isEmpty)
if (count == 0)
true
else
false
else
if (elem.head == '(')
balanceMain(elem.tail, open, count + 1)
else....
Use case match for early return purpose. It will force you to declare all return branches explicitly, preventing the careless mistake of forgetting to write return somewhere.