首页 文章

匹配类型的头/尾模式匹配参数

提问于
浏览
1

我正在研究Ninety-Nine Scala Problems的问题P07:

P07 (**) Flatten a nested list structure.
Example:
scala> flatten(List(List(1, 1), 2, List(3, List(5, 8))))
res0: List[Any] = List(1, 1, 2, 3, 5, 8)

我最初的解决方案是:

def flatten[A](ls : List[A]): List[A] = {
   def flattenRec[A](ls: List[A], flatList: List[A]): List[A] = ls match {
     case Nil => flatList
     case head: List[A] :: tail =>  flattenRec(head ::: flatten(tail), flatList)
     case head :: tail => flattenRec(tail, flatList :+ head)
   }
   flattenRec(ls, List[A]())
 }

但是这不允许't compile as I' m在第二个 case 语句中为 head 指定类型 . 有没有办法让我这样做?

顺便说一句,推荐的解决方案使用 flatMap 而不是 match ,但我不确定为什么在这种情况下甚至需要模式匹配...

2 回答

  • 0

    你可以把头部的声明括起来:

    def flatten[A](ls : List[A]): List[A] = {
      def flattenRec[A](ls: List[A], flatList: List[A]): List[A] = ls match {
        case Nil => flatList
        case (head: List[A]) :: tail => flattenRec(head, flatList)
        case head :: tail => flattenRec(tail, flatList :+ head)
      }
      flattenRec(ls, List[A]())
    }
    

    请注意,您将收到有关未选中的类型模式的警告(因为头部需要是 A 的列表,而不是因为擦除而在运行时将丢失任何其他内容),您需要确保自己可以忽略(或者通过一些涉及 TypeTag 的hijink) .

  • 5

    不错的问题和下面的替代解决方案:

    def flatten(a:List[Any]):List[Any] = 
       a.flatMap{
          case l:List[Any] => flatten(l)
          case l => List(l)
       }
    

相关问题