Scala Cannot Resolve Symbol Exit - scala

I have the following code:
def nextOption(map : OptionMap, list: List[String]) : OptionMap = {
def isSwitch(s : String) = (s(0) == '-')
list match {
case Nil => map
case "--inputFile" :: value :: tail =>
nextOption(map ++ Map('input -> value.toString), tail)
case "--schemaFile" :: value :: tail =>
nextOption(map ++ Map('schema -> value.toString), tail)
case "--outputD" :: value :: tail =>
nextOption(map ++ Map('output -> value.toString), tail)
case "--delimiter" :: value :: tail =>
nextOption(map ++ Map('delimiter -> value.toString), tail)
case option :: tail => println("Unknown option "+option)
exit(1)
}
}
The only issue is I get "Cannot Resolve Symbol Exit" in intellij. I picked this code from a popular post about accepting input parameters and it doesnt look like anyone else is getting this issue.

exit used to be defined in Predef, meaning that it was always in scope. It is now defined in package scala.sys, so just do sys.exit(1).

It was deprecated in 2.9 and replaced with sys.exit.
Related question: Scala error function deprecated. What is the alternative?

Related

Scala - head of empty list - removing all None's from a list of Options

Been trying to solve this for a while now. I need a recursive function that removes all None's from a list of Option[Int]'s, without using if-statements or using other functions.
def RemoveNone2(input: List[Option[Int]]) : List[Int] = {
input.head match {
case None => RemoveNone2(input.tail)
case _ => (input.head.get::RemoveNone2(input.tail))
}
}
val optional: List[Option[Int]] = List(Some(13), None, Some(32), None, Some(51), None, Some(17), None)
RemoveNone2(optional)
But when trying to execute the code, I get the following error:
java.util.NoSuchElementException: head of empty list
I suck at Scala, could anyone offer some insight?
You want headOption:
def RemoveNone2(input: List[Option[Int]]) : List[Int] = input.headOption match {
case None => RemoveNone2(input.tail)
case Some(head) => head :: RemoveNone2(input.tail)
}
A better way to write this is:
def removeNone(input: List[Option[Int]]) : List[Int] = input match {
case Nil => Nil
case Some(head) :: tail => head :: removeNone(tail)
case None :: tail => removeNone(tail)
An even better way is to use an accumulator, so that you can take advantage of tail-recursion:
def removeNone(input: List[Option[Int]], out: List[Int]=Nil) : List[Int] = input match {
case Nil => out.reverse
case Some(head) :: tail => removeNone(tail, head :: out)
case None :: tail => removeNone(tail, out)
}
You need to check that input list is empty to break the recursion. One of the options is to match against the list itself:
def RemoveNone2(input: List[Option[Int]]) : List[Int] = input match {
case head :: tail => head match {
case Some(value) => value :: RemoveNone2(tail)
case _ => RemoveNone2(tail)
}
case _ => Nil
}
Also note, that this implementation is not tail-recursive, whcih can lead to errors or poor performance for big collections. Tail-recursive implementation can look like that:
def RemoveNone2(input: List[Option[Int]]) : List[Int] = {
#annotation.tailrec
def inner(innerInput: List[Option[Int]], acc: List[Int]): List[Int] = innerInput match {
case head :: tail => head match {
case Some(value) => inner(tail, value::acc)
case _ => inner(tail, acc)
}
case _ => acc
}
inner(input, Nil)
}

Recursive function throw StackOverflowError

I am having problems with this function. I need to process more than 1 million records, but this crashes. Looks like just works with thousands of records and throws a StackOverflowError for a larger list. Any suggestions?
def split(list: List[(Pair, Boolean)]): List[List[Pair]] = list match {
case Nil => Nil
case head :: tail => {
val (l1, l2) = tail.span(!_._2)
(head :: l1).map(_._1) :: split(l2)
}
}
Your program will throw a StackOverflow exception:
Exception in thread "main" java.lang.StackOverflowError
at scala.collection.immutable.List.map(List.scala:283)
The reason is very simple because your method is not tail-recursive
If you annotate it with #tailrec, it won't compile:
#tailrec
def split(list: List[(Pair, Boolean)]): List[List[Pair]] = list match {
case Nil => Nil
case head :: tail => {
val (l1, l2) = tail.span(!_._2)
(head :: l1).map(_._1) :: split(l2)
}
}
The solution is to make your recusion tailrec, or use some kind of loop instead
You could try something like this:
#tailrec
def split(list: List[(Pair, Boolean)], accumulator: List[List[Pair]] = List[List[Pair]]()): List[List[Pair]] = list match {
case Nil => accumulator
case head :: tail => {
val (l1, l2) = tail.span(!_._2)
split(l2, (head :: l1).map(_._1)::accumulator)
}
}

accessing list.head, deconstruction vs method call

I am trying to learn a bit of Scala and got stuck on a small oddity when as far as I can I can write the same in two supposedly equivalent ways, but one runs and the other does not.
val test_array = Array(1,2,3,4,5,6,7,8,9,10,3,4)
val it = test_array.sliding(2).toList
def iter(lst: List[Array[Int]]): List[Boolean] = lst match {
case h :: Nil => List(false)
case h :: tail => tail.map(x => x.sameElements(lst.head)) ++ iter(tail)
}
if(iter(it).contains(true)) ...
and
val test_array = Array(1,2,3,4,5,6,7,8,9,10,3,4)
val it = test_array.sliding(2).toList
def iter(lst: List[Array[Int]]): List[Boolean] = lst match {
case h :: Nil => List(false)
case h :: tail => tail.map(x => x.sameElements(h)) ++ iter(tail)
}
if(iter(it).contains(true)) ...
The first example runs, the second throws a noSuchMethodError: scala.collection.immutable.$colon$colon.hd$1()
The only difference is how I access head. In one case I use the deconstruction way and the other I use list.head. Why does one run and the other does not?

Catching MatchError at val initialisation with pattern matching in Scala?

What is the best way (concisest, clearest, idiomatic) to catch a MatchError, when assigning values with pattern matching?
Example:
val a :: b :: Nil = List(1,2,3) // throws scala.MatchError
The best way I found so far:
val a :: b :: Nil = try {
val a1 :: b1 :: Nil = List(1,2,3)
List(a1, b1)
catch { case e:MatchError => // handle error here }
Is there an idiomatic way to do this?
Why not simply
val a::b::Nil = List(1,2,3) match {
case a1::b1::Nil => {
a1::b1::Nil
}
case _ => //handle error
}
?
Slightly improving on Kim's solution:
val a :: b :: Nil = List(1, 2, 3) match {
case x # _ :: _ :: Nil => x
case _ => //handle error
}
If you could provide more information on how you might handle the error, we could provide you a better solution.
The following doesn't catch the error but avoids (some of; see Nicolas' comment) it. I don't know whether this is interesting to the asker.
scala> val a :: b :: _ = List(1,2,3)
a: Int = 1
b: Int = 2
The simple solution is this:
List(1, 2, 3) match {
case a :: b :: Nil => .....
case _ => // handle error
}
I don't like to match twice, because it is redundant.
The "val" with pattern matching should only be used when you are sure it matches, or add a try /catch block.

How can i transform this scala function in order to be optimized

Code to determine the lat element of a list, using pattern matching:
#tailrec
def last_rec[A](list : List[A]) : A = {
list match {
case (x :: Nil) => x
case (_ :: xs) => last_rec(xs)
case Nil => throw new NoSuchElementException
}
}
I want to compile the code, I am getting "yelled" by the compiler:
PS D:\workspace\scala\P99> scalac .\P01.scala
.\P01.scala:18: error: could not optimize #tailrec annotated method last2: it contains a recursive call not in tail position
case Nil => throw new NoSuchElementException
^
one error found
If I remove the #tailrec annotation - the code compiles . How can I modify the code in order to do the tail rec optimization ?
You got a typo their. Your method is called last_rec and you are calling last which is clearly undefined. So just rename it to last. And by the way you should return Option[A] instead of A. That way you can return None when nothing is found instead of throwing the ugly NoSuchElementException.
After removing the typo and adding agilesteel's suggestion:
#tailrec
def last_rec[A](list : List[A]) : Option[A] = {
list match {
case (x :: Nil) => Some(x)
case Nil => None
case (_ :: xs) => last_rec(xs)
}
}
In this case I would do what agilesteel suggested.
However, if you really wanted to throw an exception (in another different use case), you could do it in a statically typed way:
#tailrec
def last_rec[A](list : List[A]) : Either[NoSuchElementException,A] = {
list match {
case (x :: Nil) => Right(x)
case (_ :: xs) => last_rec(xs)
case Nil => Left(new NoSuchElementException)
}
}
where later you could:
last_rec(Nil) match {
case Right(s) => println("Got a value")
case Left(e) => println("Got an exception")
}