Scala 类型列表[Any]的表达式不';t符合预期类型列表[t]
IntelliJ抱怨行first::pack(rest)上的“类型列表[Any]的表达式不符合预期的类型列表[t]”Scala 类型列表[Any]的表达式不';t符合预期类型列表[t],scala,Scala,IntelliJ抱怨行first::pack(rest)上的“类型列表[Any]的表达式不符合预期的类型列表[t]” val data = List("a", "a", "a", "b", "c", "c", "a") def pack[T](xs: List[T]): List[T] = xs match { case Nil => Nil case x :: xs1 => val (first, rest) = xs span (y =>
val data = List("a", "a", "a", "b", "c", "c", "a")
def pack[T](xs: List[T]): List[T] = xs match {
case Nil => Nil
case x :: xs1 =>
val (first, rest) = xs span (y => y == x)
first :: pack(rest)
}
pack(data)
当发现模式匹配时,原始列表为not Nil,它将至少有一个成员。这就是x::xs1。当span在条件为y=>y==x的原始列表上应用时,它应该返回一个列表。在本例中,对于第一个找到的字符“a”,它应该返回列表(a,a,a),然后与第一个匹配。
我不明白Scala为什么抱怨
目的是要有一份清单
List(List(a, a, a), List(b), List(c, c), List(a))
附言。
我的返回类型错误,应该是List[List[T]]。感谢您的帮助。现在您已经澄清了要求。您希望将
列表(列表(a、a、a)、列表(b)、列表(c、c)、列表(a))作为输入列表(“a”、“a”、“a”、“b”、“c”、“a”)的输出
val data = List("a", "a", "a", "b", "c", "c", "a")
def pack[T](xs: List[T]): List[List[T]] = {
def helper(map: Map[T, Int])(xs: List[T]): Map[T, Int] = xs match {
case Nil => map
case x :: xs =>
if (map contains x) {
helper(map + (x -> (map(x) + 1)))(xs)
} else {
helper(map + (x -> 1))(xs)
}
}
helper(Map.empty[T, Int])(xs).map { case (x, count) => List.fill(count)(x) }.toList
}
println(pack(data))
scala> println(pack(data))
List(List(a, a, a, a), List(b), List(c, c))
问题是Nil
本身属于scala.collection.immutable.Nil.type类型,因此pack
函数的整体返回类型被解释为List[Any]
因此,将case Nil=>Nil
替换为List[T]()
和first::pack(rest)
替换为x::pack(rest)
另外,比较对象时,y=>y==x
是不安全的,用y=>y.equals(x)
替换它
first
和rest
都有类型List[T]
。要连接两个列表,请使用++
,而不是:
x::pack(xs.dropWhile(==x))
?用List[T]()
替换case Nil=>Nil
,用x::pack(rest)
替换first::pack(rest)
根据您的要求编辑了我的答案。@jwvhpack
doMy point确切的意思是什么!事实上,它什么也没做。我认为OP考虑的是删除相邻的重复项。如果是这样的话,那么维克多·莫洛兹的建议就是前进的方向。我不认为那是OP想要的,但我以前就错了。希望@johnsam最终会站出来解释代码应该做什么。谢谢,我在你的回答中发现了我的问题,我的返回类型是错误的。我认为你不需要返回List。空[List[t]]表示为零。y=>y==x非常好,不y==x
实际上,在某些特殊情况下,例如Double.NaN==Double.NaN
时,它的行为与应该的行为不同。是的,Nil
在这里不会引起太多问题,但它确实会混淆复杂情况下的类型推断。请记住,显式编程永远不会有什么坏处,它还可以使代码更具可读性。
val data = List("a", "a", "a", "b", "c", "c", "a")
def pack[T](xs: List[T]): List[List[T]] = xs match {
case Nil => List.empty[List[T]]
case x :: xs1 => {
val (first, rest) = xs.span(t => t.equals(x))
first :: pack(rest)
}
}
pack(data)