12
votes

I am new to Scala, just started learning, so this is basic beginner question.

I try to implement Sieve of Eratosthenes algorithm. Here is what I got so far:

def sieve_core(cross: Int, lst: Seq[Int]): List[Int] = {
    val crossed = lst.filter(_ % cross != 0)
    crossed match {
            case a :: rest => cross :: sieve_core(a, crossed)
            case _ => cross :: Nil
    }
}

def sieve(max: Int): List[Int] = {
    sieve_core(2, (2 to max))
}

println(sieve(100))

The result is:

List(2)

As far as I understand, case _ => cross :: Nil is matched in first iteration of sieve_core, which means that crossed is not an instance of a List.

I changed lst parameters type to List[Int] and now the code won't compile with an error:

(fragment of Problem3.scala):24: error: type mismatch;
 found   : Range.Inclusive
 required: List[Int]
    sieve_core(2, (2 to max))
                      ^

Apparently Range is not a List.

Question: how can I turn Range into a List? Or is it some bigger problem with my code, I have made some bad assumption somewhere along the way?

Any help appreciated.

3

3 Answers

33
votes

There's an apply method on the List companion object which takes a range and returns a List:

scala> List.range(2, 11)
res0: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)

There are lots of useful List factory methods in the List collection documentation.

7
votes

To turn any sequence s into a list, use s.toList

I'm sure digitalross' is more efficient in this case, though.

0
votes

(2 to max) is not a scala.collection.immutable.List indeed but a scala.collection.immutable.Range, more precisely an instance of scala.collection.immutable.Range.Inclusive, as mentioned in your error message. Just in passing note that Inclusive and Exclusive are themselves members of Range, with a fairly auto-explanatory meaning.

Luckily the Range class offers the handy method toList, which you can leverage for converting the range into a list and resolve the problem, like in the following code snippet:

scala> val max = 10
max: Int = 10

scala> val r = (2 to max)
r: scala.collection.immutable.Range.Inclusive = Range 2 to 10

scala> val l = r.toList
l: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)