【发布时间】:2016-03-10 23:05:37
【问题描述】:
我想pattern matchscala 中list 的不同段上head 和tail 的类型:
class Solution07 extends FlatSpec with ShouldMatchers {
"plain recursive flatten" should "flatten a list" in {
val list1 = List(List(1, 1), 2, List(3, List(5, 8)))
val list1Flattened = List(1, 1, 2, 3, 5, 8)
flattenRecur(list1) should be (list1Flattened)
}
def flattenRecur(ls: List[Any]): List[Int] = ls match {
case (head: Int) :: (tail: List[Any]) => head :: flattenRecur(tail)
case (head: List[Int]) :: (tail: List[Any]) => head.head :: flattenRecur(head.tail :: tail)
case (head: List[Any]) :: (tail: List[Any]) => flattenRecur(head) :: flattenRecur(tail) // non-variable type... on this line.
}
}
我明白了:
错误:(18, 17) 类型模式中的非变量类型参数 Int List[Int](List[Int] 的底层)未选中,因为它是 通过擦除消除 case (head: List[Int]) :: (tail: List[Any]) => head.head :: flattenRecur(head.tail :: tail) ^
我错过了什么?我怎么可能对列表中的head 和tail 的类型 进行模式匹配?
【问题讨论】:
-
尝试将
case (head: List[Int]) :: (tail: List[Any]) =>替换为case ( (headhead : Int) :: (headtail : List[Any]) ) :: (tail : List[Any]) =>,这样你就可以对抗类型擦除 -
问题在于
case (head: List[Any]) :: (tail: List[Any])行,您提到了不同的行,这也应该有助于该行吗??? -
第三个选项与第二个选项冲突。所以你可以调整第二个选择或第三个选择。由于第三个选择更笼统,因此更容易使第二个更具体
-
您是否声称我不需要第三种情况:
case (head: List[Any]) :: (tail: List[Any]),因为它有冲突? -
我想您的某些功能需要所有选择。您也不应该丢弃。问题在于 scala 的类型擦除,无法区分第二个和第三个选择。因此,您应该更多地扩展第二选择以使类型与众不同。对于匹配所有类型的 scala 模式 List[blabla] 是相同的。但是您可以获取 List 的负责人并为其指定类型。并且该类型将被正确检查。在第二个选择中,
head的类型是 List[Int],它没有描述。所以你应该将head进一步扩展为headhead :: headtail。现在 scala 会捕获类型