I just start learning scala. I got an error "illegal start of simple expression" in eclipse while trying to implement a recursive function:
def foo(total: Int, nums: List[Int]):
if(total % nums.sorted.head != 0)
0
else
recur(total, nums.sorted.reverse, 0)
def recur(total: Int, nums: List[Int], index: Int): Int =
var sum = 0 // ***** This line complained "illegal start of simple expression"
// ... other codes unrelated to the question. A return value is included.
Can anyone tell me what I did wrong about defining a variable inside a (recursive) function? I did a search online but can't one explains this error.
A variable declaration (var) doesn't return a value, so you need to return a value somehow, here's how the code could look like:
object Main {
def foo(total: Int, coins: List[Int]): Int = {
if (total % coins.sorted.head != 0)
0
else
recur(total, coins.sorted.reverse, 0)
def recur(total: Int, coins: List[Int], index: Int): Int = {
var sum = 0
sum
}
}
}
The indentation seems to imply that recur is inside count, but since you did not place { and } surrounding it, count is just the if-else, and recur is just the var (which is illegal -- you have to return something).
I had a similar problem where I was doing something like
nums.map(num =>
val anotherNum = num + 1
anotherNum
)
and the way to fix it was to add curly braces:
nums.map { num =>
val anotherNum = num + 1
anotherNum
}
I thought these expressions were equivalent in Scala, but I guess I was wrong.
I had a similar problem. Found example 8.1 in the book that looked like:
object LongLines {
def processFile(filename: String, width: Int) **{**
val source = Source.fromFile(filename)
for (line <- source.getLines)
processLine(filename, width, line)
**}**
Note: the "def processFile(filename: String, width: Int) {" and ending "}"
I surrounded the 'method' body with {} and scala compiled it with no error messages.
Related
object perMissing {
def solution(A: Array[Int]): Int = {
def findMissing(i: Int, L: List[Int]): Int = {
if (L.isEmpty || L.head != i+1) {
i+1
println(i+1)}
else findMissing(i+1, L.tail)
}
if (A.length == 0) 1
else findMissing(0, A.toList.sorted)
}
solution(Array(2,3,1,5))
}
I'm new to the world of Scala. I come from Python and C world.
How do we print an integer value, eg. for debugging? For instance, if I want to see the value of i in every iteration.
I compile my code using scalac and run it using scala.
According to the signature of your findMissing function, it should return an Int. However, if you look at the implementation of that function, only one of the code paths (namely the else part) returns an Int - the if part on the other hand does not return anything (besides Unit), since the call to println is the last line of that particular code block. To fix this issue, just return the increased value by putting it at the end of the block:
def findMissing(i: Int, l: List[Int]): Int = {
val inc = i + 1
if (l.isEmpty || l.head != inc) {
println(inc)
inc
}
else findMissing(inc, l.tail)
}
Since findMissing is tail recursive, you could additionally annotate it with #tailrec to ensure it will be compiled with tail call optimization.
I am new to Scala and working on a project. I am writing a function that is suppose to return the smallest Int in an array. However when I run it I get a type error that it is returning unit instead of int.
Here is my code:
def minWhile(r: Array[Int]): Int = {
var pos = 1
var minInt = r(0)
while (pos < r.length) {
if (r(pos) < minInt)
minInt = r(pos)
pos += 1
}
minInt
}
Thank you very much!
Your code is compiled correctly, because it always returns correct type Int. But it may cause some runtime exceptions, if we passed empty array into your function: minWhile(Array()).
def minWhile(r: Array[Int]): Int =
{
var pos = 1
var minInt = r(0) /* potential runtime exception */
while( pos < r.length){
if(r(pos) < minInt)
minInt = r(pos)
pos+=1
}
minInt
}
You have to check arrays bounds working with it.
Or you can use a shorter way:
def minWhile(r: Array[Int]): Option[Int] = if (r.nonEmpty) Some(r.min) else None
Your code should be compiled correctly but it may rise an exception when passed empty container. You are using variables which is discouraged.
I would do it using some recursion calls or scala collections API like so:
array.reduceLeft(a: Somehitng, b: Something => Something)
Check thia link:
http://m.alvinalexander.com/scala/scala-use-reduceleft-get-max-min-from-collection
Consider this more functional style of conveying the semantics of minWhile, as follows,
def minWhile(r: Array[Int]): Int = {
(r zip r.drop(1)).takeWhile(t => t._1 > t._2).last._2
}
where we zip consecutive items and take those monotonically decreasing. The desired result is found in the second part of the last duple.
Below is a simple 'repeat' method I am trying to write using tail recursion. The sole purpose of this function is to just repeat the giving string back to back 'n' amount of times.
I.e. repeat("Hello",3) = "HelloHelloHello"
But for whatever reason I am getting a 'java.lang.UnsupportedOperationException' and I am not sure why.
P.S. This is a homework assignment so if I could just be pointed in the right direction instead of a straight answer that would be cool!
def repeat(s: String, n: Int): String = {
def tailRepeat(str: String, x: Int): String = x match {
case `n` => str
case _ => val repeatString = s + str
tailRepeat(repeatString, (x + 1))
}
tailRepeat(s, 0)
}
I think you are making this a little too complex. For one thing you don't really need pattern matching at all, you have a counting variable that tells you how many times to repeat your string, using that would simplify your code greatly. Also it is usually more straightforward to count down and not up:
def repeat(s: String, n: Int): String = {
def tailRepeat(str: String, x: Int): String = {
if(x == 0) str
else tailRepeat(str + s, x - 1)
}
tailRepeat(s, n - 1)
}
println( repeat("hello", 3) );
// hellohellohello
I'm newbie in using Scala, and most of the time I don't know how to deal with error messages. Can someone help me with this code? What do I need to change to make this code work? Btw, I'm writing Euklid's Greatest Common Divisor in Scala.
def userInput() {
var x: String = Console.readLine("Please enter the first number you want to calculate. ")
var y: String = Console.readLine("Please enter the second number you want to calculate. ")
println(userInput())
}
def ggt(firstNumber: Long, secondNumber: Long): Long = {
var x = firstNumber
var y = secondNumber
if (y == 0) {
return x
}
}
And the error I get is "type mismatch; found : Unit required: Long" in this line:
if (y == 0) {
What should I change? Thanks in advance for your guys help!
Your ggt function needs to return a Long and it's not always doing so. First, you can remove the return keyword because scala functions will always return whatever is on the last line. Then, you need a return value when y != 0 to make this function definition valid. Right now, it's returning Unit which is like void because there is no else block there. Change to something like this and you should be all set:
def ggt(firstNumber: Long, secondNumber: Long): Long = {
var x = firstNumber
var y = secondNumber
if (y == 0) x
else y
}
First, if you want to read numbers from the command line, then your userInput is incorrect, it should be something like this:
def readNumbers(): (Long, Long) = {
println("Print the first number")
val first = Console.readLong()
println("Println the seconds number")
val second = Console.readLong()
(first, second)
}
Then read numbers:
val (a, b) = readNumbers()
GCD method:
def gcd(a: Long, b: Long): Long = if (b == 0) a else gcd(b, a % b)
and call it on the numbers:
gcd(a, b)
Scala is a functional on the one hand, so every expression results in some value, and in Scala if is an expression, not a statement.
Some algorithms execute a while loop with condition true and will (for sure) end at some point with a return statement inside the body of the while loop. E.g.:
def foo: Int = {
while(true) {
// At some time, the while loop will do a return statement inside its body
if( ... )
return 0
}
}
Simple example (without semantic sense):
def foo: Int = {
var i = 0
while(true) {
i += 1
if(i == 10)
return 0
}
}
The Scala compiler complains about a type mismatch, because the while loop has type Unit and the compiler does not know, that the while loop will at some point return a value. We could fix this with a workaround like:
def foo: Int = {
var i = 0
while(true) {
i += 1
if(i == 10)
return 0
}
0 // !
}
But this looks ugly. Is there a better workaround ? Or even a better solution for this kind of problem ?
You could throw an exception:
def foo: Int = {
var i = 0
while(true) {
i += 1
if(i == 10)
return 0
}
throw new IllegalStateException("This should never happen")
}
The compiler will stop complaining about the type mismatch, and since the while loop always returns something, the exception will never be thrown. And if it is, you will quickly find out where you did something wrong :).
There are other ways to write this loop which are more idomatic and Scala-esque, but given the code you provided, this will get the job done in a clear and simple way.
Maybe you should just use tail recursion instead. It should end up compiling down to very similar bytecode:
import scala.annotation.tailrec
def foo: Int = {
#tailrec def bar(i: Int): Int = {
val j = i + 1
if (j == 10) return 0
else bar(j)
}
bar(0)
}
You might even want to make use of the default parameter value support:
#tailrec def foo(i: Int = 0): Int = {
val j = i + 1
if (j == 10) return 0
else foo(j)
}
Note that this way requires you to call the function as foo() not foo since it has an argument.
A more idiomatic way would be to use recursion. Something like this:
def foo: Int = {
import scala.annotation.tailrec
#tailrec def whileUnderTen(i: Int):Int = if ( i < 10) whileUnderTen(i+1) else 0
whileUnderTen(0)
}
For just these occasions, I have a "forever" construct defined in my personal standard library.
forever{
}
is in all ways equivalent to
while(true){
}
except that forever has type Nothing while the equivalent while construct has type Unit. Just one of those small extension capabilities that makes Scala such a joy.