0

I have an input List

var list=List(List(1, 1), 2, List(3, List(5, 8)))

and i need it to be flattened as "List(1, 1, 2, 3, 5, 8)".

since my input list contains List[Int],Int,List[Any],i cannot flatten it using the flatten function.so i wrote my own flat function.

object HelloWorld {
   def main(args: Array[String]) {
     println(flat(List(List(1, 1), 2, List(3, List(5, 8)))))
     //println(flat(List(List(1, 1), 2, List(3, 4))))
   }

   def flat(lst:List[Any]):List[Any]={
       lst.flatMap{
           case a:List[Int] => a
           case b:Int => List(b)
           case c:List[Any] => flat(c)
       }
   }
} 

I am leaving the input as it is if it is List[Int],for an integer i am converting it into a List and for a List[Any], i am recursively calling my own flat function.

The code executes but i am not getting my desired output.Apart from that,i receive two warnings.

o/p :List(1, 1, 2, 3, List(5, 8))

jdoodle.scala:5: warning: non-variable type argument Int in type pattern List[Int] (the underlying of List[Int]) is unchecked since it is eliminated by erasure case a:List[Int] => a ^

jdoodle.scala:7: warning: unreachable code case c:List[Any] => flat(c) ^ warning: there was one deprecation warning (since 2.13.0); re-run with -deprecation for details

Any idea where i am going wrong.Much appreciated.

Note:I am able to get the desired o/p using the below code

object HelloWorld {
   def main(args: Array[String]) {
      println(flat(List(List(1, 1), 2, List(3, List(5, 8)))))
   }

 def flat(list: List[Any]): List[Any] = { list.flatMap{

  case i: List[Any] => flat(i)

  case e => List(e)

 } 

 }

}

I just need to know why the 1st approach at the beginning wouldnt work.

Gaurav Gupta
  • 159
  • 1
  • 17
  • 2
    The first approach won't work due type erasure. In any case, having a **List[Any]** is a code smell. Maybe you can avoid this problem by rethinking your design. Why did you end up in this situation? – Luis Miguel Mejía Suárez May 04 '20 at 17:01
  • @ Luis Miguel Mejía Suárez I tried reading about type Erasure but i couldn't understand it.Can you elaborate what is it and how it is affecting my code.(yes having List[Any] is not a good practice.) – Gaurav Gupta May 04 '20 at 17:28
  • 1
    [Types only exists at compile-time, at runtime there are only classes](https://typelevel.org/blog/2017/02/13/more-types-than-classes.html). Thus, at runtime there is no **List[Int]** or **List[Any]**, only **List** _(as a class)_. Pattern matching works on runtime, thus you can not check if your object is a **List[Int]** or a **List[Any]**, only that it is an instance of the **List** class. – Luis Miguel Mejía Suárez May 04 '20 at 17:34
  • @Luis Miguel Mejía Suárez oh ok,so basically List[Any],List[Int],List[String] are basically the same when it comes to pattern matching in scala and that is how i was getting another warning that List part of code is unreachable. – Gaurav Gupta May 04 '20 at 17:39
  • 2
    Yes, exactly that. Note that, this is not a limitation of Scala perse, but of the JVM. It also applies to any language that runs over it. In general, that is one of the reasons why pattern matching by type is considered a bad practice. – Luis Miguel Mejía Suárez May 04 '20 at 17:43
  • @Luis Miguel Mejía Suárez oh ok,thanks mate.i have a clear understanding now. – Gaurav Gupta May 04 '20 at 17:46

0 Answers0