Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 类型列表[Any]的表达式不';t符合预期类型列表[t]_Scala - Fatal编程技术网

Scala 类型列表[Any]的表达式不';t符合预期类型列表[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 =>

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 => 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)
根据您的要求编辑了我的答案。@jwvh
pack
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)