传递 Set[List[Int]] 类型值而不是 List[Int] - 为什么会这样?

Ely*_*Ely 1 types scala signature

当我查看签名和函数调用时,我很难理解以下内容。

在我的工作表中,我有以下内容(摘自 Coursera 讲座):

 object nqueens {

  def queens(n: Int) : Set[List[Int]] = {
    def placeQueens(k: Int) : Set[List[Int]] =
      if (k == 0) Set(List())
      else
      for  {
        queens <- placeQueens(k - 1)
        col <- 0 until n
        if isSafe(col, queens)
      } yield col :: queens
    placeQueens(n)
  }

  def isSafe(col: Int, queens: List[Int]) : Boolean = {
    val row = queens.length
    val queensWithRow = (row - 1 to 0 by -1) zip queens
    queensWithRow forall {
      case (r, c) => col != c && math.abs(col - c) != row -r
    }
  }

  def show(queens: List[Int]) = {
    val lines =
      for (col <- queens.reverse)
        yield Vector.fill(queens.length)("* ").updated(col, "X ").mkString
    "\n" + (lines mkString "\n")
  }

  (queens(4) map show) mkString "\n"

}
Run Code Online (Sandbox Code Playgroud)

考虑到签名placeQueenisSafe

def placeQueens(k: Int) : Set[List[Int]]

def isSafe(col: Int, queens: List[Int]) : Boolean
Run Code Online (Sandbox Code Playgroud)

我想知道它为什么有效。我们调用placeQueens并将结果保存在queens(在for循环中)。

结果应该是类型Set[List[Int]]。然后我们isSafe使用Intand 的两个参数调用Set[List[Int]]- 但我不明白为什么会这样,因为queensshould 是类型Set[List[Int]],而参数isSafeshould List[Int]

Vik*_*ram 5

我们调用 placeQueens 并将结果保存在 Queens 中

您的代码没有保存placeQueensinto的结果queens

for  {
    queens <- placeQueens(k - 1)
    col <- 0 until n
    if isSafe(col, queens)
  } yield col :: queens
Run Code Online (Sandbox Code Playgroud)

这段代码实际上用于理解。有问题的特定行:

queens <- placeQueens(k-1) 
Run Code Online (Sandbox Code Playgroud)

正在将 a 存储List[Int]到皇后中,因为它正在迭代从Set[List[Int]]返回的placeQueens. 举一个更简单的例子来帮助说明正在发生的事情,请考虑:

val a = Set(1,2,3)
val b = for (x <- a) yield x + 2
Run Code Online (Sandbox Code Playgroud)

执行此代码后,bSet(3,4,5). 这是因为在 for 循环中的每次迭代中,x首先是 1,然后是 2,然后是 3。