调用扁平化无法在一个用例上编译但在另一个用例上有效

Call to flatten fails to compile on one use case but works on the other

我想展平一组序列:

val test = for(i <- 1 to 3) yield {
  if(i == 1)
    Set.empty
  else
    Set(9, 1)
}
val b = test.flatten

这失败了:

ScalaFiddle.scala:7: error: No implicit view available from scala.collection.immutable.Set[_ <: Int] => scala.collection.GenTraversableOnce[B]. val b = test.flatten ^ ScalaFiddle.scala:7: error: not enough arguments for method flatten: (implicit asTraversable: scala.collection.immutable.Set[_ <: Int] => scala.collection.GenTraversableOnce[B])scala.collection.immutable.IndexedSeq[B]. Unspecified value parameter asTraversable. val b = test.flatten

但真正让我困惑的是为什么这有效?:

val test = for(i <- 1 to 3) yield {
  if(i == 1)
    Set.empty
  else
    Set(9, 1)
}
println(test.flatten)
// compiles and prints Vector(9, 1, 9, 1) when run

所以我的问题是:println(test.flatten) 中的扁平化和 val b = test.flatten 中的扁平化调用有什么区别?

感谢 Michael Zajac 的评论,我让它工作了。

两者都

val test = for(i <- 1 to 3) yield {
  if(i == 1)
    Set.empty[Int]
  else
    Set(9, 1)
}
val b = test.flatten

val test = for(i <- 1 to 3) yield {
  if(i == 1)
    Set.empty
  else
    Set(9, 1)
}
val b: Seq[Int] = test.flatten

应该可以。在 Set.empty 上设置类型或告诉编译器我们期望 val b.

的类型

或者,应该可以反转您的条件并使其成为 for 中的守卫,并在那里使用您的 Set

val b = for {
  i <- 1 to 3
  if i != 1
  j <- Set(9, 1)
} yield j

// b: scala.collection.immutable.IndexedSeq[Int] = Vector(9, 1, 9, 1)