在 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
,而c
是List[Int]
类型,所以在我看来,_:::c
应该是两个 List[Int]
的串联。应该符合预期的类型吧?
ls
- List[Int]
类型的列表
foldLeft
- 从 ls
的 Int
元素创建新内容。
List[Int]()
- 新事物将是另一个 List[Int]
。从一个空的开始。
(c, _)
- 每一步都接收到正在构建的 List
,我们将其称为 c
,以及来自 ls
的 Int
,但是不要给它起名字(即扔掉它)。
_:::c
- 尝试将 2 个列表连接在一起。一个是我们正在构建的 c
列表,另一个是……什么都没有。它不是 List
或 Int
。这是一个未命名的参数,但我们没有这些参数。在接收到的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 编译器:
- 我有两个agruments的功能:
c
另一个被丢弃了。
- 这个函数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])(_.::(_))
正在使用 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
,而c
是List[Int]
类型,所以在我看来,_:::c
应该是两个 List[Int]
的串联。应该符合预期的类型吧?
ls
-List[Int]
类型的列表
foldLeft
- 从ls
的Int
元素创建新内容。List[Int]()
- 新事物将是另一个List[Int]
。从一个空的开始。(c, _)
- 每一步都接收到正在构建的List
,我们将其称为c
,以及来自ls
的Int
,但是不要给它起名字(即扔掉它)。_:::c
- 尝试将 2 个列表连接在一起。一个是我们正在构建的c
列表,另一个是……什么都没有。它不是List
或Int
。这是一个未命名的参数,但我们没有这些参数。在接收到的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 编译器:
- 我有两个agruments的功能:
c
另一个被丢弃了。 - 这个函数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])(_.::(_))