14

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 Answers 3

39

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.

Sign up to request clarification or add additional context in comments.

5 Comments

I checked List class apidocs, haven't checked List object docs. Now I know better. Thanks.
You know, it's super annoying how they aren't prominently linked to each other, or even combined into a single page :)
This is supposed to be deprecated, I'm told. 2 to max toList will work.
Thanks, I revised the answer. 2.7.3 docs released in January 2009 gave no hint...
caution: the very nice option of dropping the "." may still require you to add parens later for methods with no arguments: 2 to 4 toList reverse parses as .toList(reverse), so you need (2 to 4 toList) reverse or (2 to 4).toList reverse or more conventionally, 2.to(4).toList.reverse - but I still drop the ".()" if I can.
7

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

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

Comments

0

(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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.