如何创建函数以从任意深度嵌套的列表中生成平面列表?

Stu*_*man 6 scala shapeless

是否可以在scala中编写函数,该函数将采用任意深度嵌套的列表的列表并将其递归转换为平面列表?例如:

flatten(List(List(1), List(List(2), 3), 4))
Run Code Online (Sandbox Code Playgroud)

应该回来

List(1,2,3,4)
Run Code Online (Sandbox Code Playgroud)

我做了一些尝试,shapeless但没有效果:

object flatten extends (List ~> List) {
    def apply[T](s: List[T]) = s.map {
       case l: List[T] => apply(s)
       case x => x
    }
}
Run Code Online (Sandbox Code Playgroud)

这给了我:

类型不匹配

找到:清单[任何]

必填:列表[T]

如果可以推导正确的类型(在示例List[Int]而不是List[Any]),也将很棒

Xav*_*hot 8

关键是,你不接受List[T]输入,但List[Any]这里Any是一个混合TList[Any]

因此,如果您知道叶子元素的类型,则可以T通过在T或上进行递归模式匹配来潜在地使用类型参数来表示它和平面图元素List[Any]

import scala.reflect.ClassTag

def flatten[T: ClassTag](list: List[Any]): List[T] =
  list.flatMap {
    case x: T => List(x)
    case sub: List[Any] => flatten[T](sub)
  }

flatten[Int](List(List(1), List(List(2), 3), 4))
// List[Int] = List(1, 2, 3, 4)
Run Code Online (Sandbox Code Playgroud)