如何在 Scala foldLeft 中使累加器成为 Int 的空集?

How to make accumulator an Empty Set of Int in Scala foldLeft?

我目前在 Scala 中有一个大小大于 1 的集合:

val x = BitSet(19, 49)
val z = HashMap(49 -> HashSet(5, 6, 9, 13, 3, 8, 4), 19 -> Set(5, 9, 14)) 类型 Map[Int,Set[Int]]

我正在尝试使用 foldLeft 构造一个 Set[Int],其中所有值都与 Set x 中的元素关联,最终结果将是:HashSet(5, 6, 9, 13, 3, 8, 4, 14),但我无法将累加器正确设置为 Set[Int].

我没有使用 x.foldLeft(Set(0))((acc, elem) => acc.union(z(elem))) 然后从最终集合中删除元素 0

我试过了x.foldLeft(Set.empty)((acc, elem) => acc.union(z(elem)))

type mismatch found   : 
Set[Int]     (in scala.collection.immutable) 
required: Set[Nothing] (in scala.collection) 

我什至尝试创建一个空的 Set[Int] 作为变量并在折叠表达式中使用它,但它也没有用。我不能将 Set(0) 保留为累加器的初始值,因为它可能作为实际值出现。

除了 1 个小错误外,代码完全没问题。 x.foldLeft(Set.empty)((acc, elem) => acc.union(z(elem)))

有一些方法可以解决这个问题:

1. x.foldLeft(Set.empty[Int])((acc, elem) => acc.union(z(elem)))
2. x.foldLeft[Set[Int]](Set.empty)((acc, elem) => acc.union(z(elem)))

TL;DR

如果我们深入挖掘 scala 代码,这就是 foldleft

的签名

def foldLeft[B](z: B)(op: (B, A) => B): B

这个 curry 函数有 2 个部分,第一个 def foldLeft[B](z: B) 而第二个部分包含 op,它将在迭代期间应用。

让我们了解编译器将如何推断泛型。 x.foldLeft[?](Set.empty[?]) 这里的 Set.empty 问号将替换为默认的 Nothing 但在 ops 函数中,参数 acc 的类型为 Set[int]。这将导致类型不匹配。

要解决编译问题,我们需要在 Set.empty 中提供类型参数,或者在 foldLeft 之前明确提供类型,以便 Set.empty 正确的类型将被编译器红外线。