views:

344

answers:

2

compiling this code in scala 2.7.6:

def flatten1(l: List[Any]): List[Any] = l.flatten

i get the error:

no implicit argument matching parameter type (Any) = > Iterable[Any] was found

why?

+4  A: 

The documentation:

Concatenate the elements of this list. The elements of this list should be a Iterables. Note: The compiler might not be able to infer the type parameter.

Pay close attention to that second sentence. Any cannot be converted to Iterable[Any]. You could have a list of Ints, and that list cannot be flattened since Int is not iterable. And think about it, if you have List[Int], what are you flattening? You need List[B <: Iterable[Any]], because then you would have two dimensions, which can be flattened to one.

geowa4
scala> val l = List(1, 2, List(3, 4))l: List[Any] = List(1, 2, List(3, 4))so does this mean I can't flatten list of Int? what lists can i flatten then?
IttayD
*@Ittay* - see my answer - you need to convert the `List[Any]` which you've provided to a `List[Iterable[A]]` for some A.
oxbow_lakes
you can flatten a list of iterables, i.e. a list of lists of ints.
geowa4
+4  A: 

If you are expecting to be able to "flatten" List(1, 2, List(3,4), 5) into List(1, 2, 3, 4, 5), then you need something like:

implicit def any2iterable[A](a: A) : Iterable[A] = Some(a)

Along with:

val list: List[Iterable[Int]] = List(1, 2, List(3,4), 5) // providing type of list 
                                                         // causes implicit 
                                                         // conversion to be invoked

println(list.flatten( itr => itr )) // List(1, 2, 3, 4, 5)

EDIT: the following was in my original answer until the OP clarified his question in a comment on Mitch's answer

What are you expecting to happen when you flatten a List[Int]? Are you expecting the function to sum the Ints in the List? If so, you should be looking at the new aggegation functions in 2.8.x:

val list = List(1, 2, 3)
println( list.sum ) //6
oxbow_lakes
I was interested in your original answer. Yet I can't understand why it needs to be so cumbersome.
IttayD
cumbersome? why are you trying to flatten a possibly flat list? how is scala supposed to know how you want to flatten a list filled with anything?
geowa4
def flatten(l: List[Any]): List[Any] = l flatMap { case l: List[_] => flatten(l); case e => List(e); }
IttayD