在 Scala 中反转列表时,类型 B => List[B] 的表达式不符合预期类型 List[Int]

Expression of type B => List[B] doesn’t conform to expected type List[Int] when reverse a list in Scala

正在使用 foldLeft 函数在 Scala 中处理一个反转列表的函数:

def reverseWithFold(ls: List[Int]): List[Int] =
        ls.foldLeft(List[Int]())((c, _) => _:::c)

出现编译错误:Expression of type List[B_] => List[Int] doesn’t comforrm to expected type List[Int](PS:我知道我的解决方案不正确)

我能知道这是什么意思吗?在_:::c这里,_代表(c, _)中的c,而cList[Int]类型,所以在我看来,_:::c 应该是两个 List[Int] 的串联。应该符合预期的类型吧?

  • ls - List[Int]
  • 类型的列表
  • foldLeft - 从 lsInt 元素创建新内容。
  • List[Int]() - 新事物将是另一个 List[Int]。从一个空的开始。
  • (c, _) - 每一步都接收到正在构建的 List,我们将其称为 c,以及来自 lsInt,但是不要给它起名字(即扔掉它)。
  • _:::c - 尝试将 2 个列表连接在一起。一个是我们正在构建的 c 列表,另一个是……什么都没有。它不是 ListInt。这是一个未命名的参数,但我们没有这些参数。在接收到的2个参数中,一个被命名为c,另一个被丢弃。

这是一种解决方法:(c, n) => List(n):::c(将 2 个列表连接在一起)

这里有一个更好的修复方法:(c, n) => n::c(在此列表的头部添加一个新元素)

使用未命名参数:ls.foldLeft(List[Int]())(_.::(_))

你看,你可以写List(1,2,3).reduce((x, y) => x + y)List(1,2,3).reduce(_ + _)。这里,(x, y) => x + y_ + _ 是函数,第一个更明显,第二个是函数,其中每个下划线被一个参数替换。

您在这里所做的是 (c, _) => _:::c 试图将两者结合起来。但是,实际上,您只是告诉 scala 编译器:

  1. 我有两个agruments的功能:c另一个被丢弃了。
  2. 这个函数returns没有指定类型的函数。 (示例:(Int, Int) => (Int => Int) = (a: Int, _) => _ * 2

您在这里可以做的是

仅使用下划线重写:

ls.foldLeft(List.empty[Int])(_.::(_))

或重写而不丢弃:

ls.foldLeft(List.empty[Int])((acc, cur) => cur :: acc)

下划线不是有效的变量名,它们用于忽略变量。 (c, _)_ ::: c中的两个下划线是不相关的。

  • (c, _) => { ... }完全忽略第二个参数,没了
  • _ ::: c 是 lambda 表达式 x => x ::: c 的快捷方式,它期望一个 x 是一个 List[B_] 对于某些未知类型 B_ 不能被推断,因为它不是预期的,并且在您的代码中无处可寻。

如果您想将第二个参数添加到第一个参数之前,您必须编写类似

的内容
ls.foldLeft(List.empty[Int])((c, x) => x :: c)

甚至

ls.foldLeft(List.empty[Int])(_.::(_))