How to pattern match head and tail types of a scala list?

让人想犯罪 __ 提交于 2019-12-05 05:47:28

I agree that @Andreas solution with HList is a nice example for solving the problem, but I still do not understand what's the problem with this:

 def flatten(ls: List[_]): List[Int] = ls match {
    case Nil => Nil
    case (a: Int) :: tail => a :: flatten(tail)
    case (a: List[_]) :: tail => flatten(a) ::: flatten(tail)
    case _ :: tail => flatten(tail)
  }

Then:

println(flatten(List(List("one",9,8),3,"str",4,List(true,77,3.2)))) // List(9, 8, 3, 4, 77)

I don't see any problems with type erasure in your task, because you actually don't need to test the types that are erased. I've intentionally skipped all erased types in my example - to show this. Type erasure does not clear the type information of the elements of the list, it clears only the type information of list generic which you have Any or _ in my case - so you do not need that at all. If I am not missing someting, in your example the types are not erased at all, because you anyway have Any almost everywhere.

You are hit by restrictions given by the object system:

The only common parent for List[Int] and Int is Any

So due to that the inference system can only safely assume that you could return Any. The solution proposed @jwvh is doable but has a possible danger of runtime exceptions.

If you want to solve the problem in a typesafe way an option could be to use HList of the shapeless library https://github.com/milessabin/shapeless : https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#heterogenous-lists

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!