Scala的理解中的类型不匹配

时间:2018-07-03 07:05:51

标签: scala

我试图定义一个类似于以下内容的递归Scala函数:

  def doSomething: (List[List[(Int, Int)]], List[(Int, Int)], Int, Int) => List[Int] =
  (als, rs, d, n) =>
    if (n == 0) {
      for (entry <- rs if (entry._1 == d)) yield entry._2
    } else {
      for (entry <- rs; adj <- als(entry._1)) yield doSomething(als, rs.::((adj._1, adj._2 + entry._2)), d, n - 1)
    }

现在,编译器告诉我:

  

| | | | | | <console>:17: error: type mismatch; found : List[List[Int]] required: List[Int] for (entry <- rs; adj <- als(entry._1)) yield doSomething(als, rs.::((adj._1, adj._2 + entry._2)), d, n - 1) ^

我不知道是什么问题。我确定我正确使用了<-。另一方面,我是来自Java世界的Scala新手...

关于输入的类型:

alsList[List[(Int,Int)]]

rsList[(Int,Int)]

dnInt

我告诉IntelliJ将我的代码发送到Scala控制台后,就会出现编译器错误。

2 个答案:

答案 0 :(得分:5)

yield上迭代时AList时,返回List[A]doSomething返回一个List[Int],因此,让您返回List[List[Int]]。您可以像这样展开:

def doSomethingElse(als: List[List[(Int, Int)]], rs: List[(Int, Int)], d: Int, n: Int): List[Int] =
  if (n == 0) {
    for ((k, v) <- rs if k == d) yield v
  } else {
    for {
      (k, v) <- rs
      (adjk, adjv) <- als(k)
      item <- doSomethingElse(als, (adjk, adjv + v) :: rs, d, n - 1)
    } yield item
  }

请注意,为了简洁起见,我还使用了一种方法符号并解构了对,并利用名称以:结尾的方法的右关联性,以提高可读性,请随意使用您可能想要的任何约定(但是我不愿意真的看不到为什么要有一个返回常量函数的方法(也许您只想用val来声明它)。

作为进一步的说明,您正在对线性序列(als(k))使用随机访问,您可能需要考虑索引序列(例如Vector)。可以在here中找到有关Scala Collection API复杂性特征的更多信息。

答案 1 :(得分:2)

出于测试目的,我创建了一些符合以下输入数据类型的示例数据

val als = List(List((1,2), (3,4)), List((1,2), (3,4)), List((1,2), (3,4)))
//als: List[List[(Int, Int)]] = List(List((1,2), (3,4)), List((1,2), (3,4)), List((1,2), (3,4)))
val rs = List((1,2), (2,3))
//rs: List[(Int, Int)] = List((1,2), (2,3))
val d = 1
//d: Int = 1
val n = 3
//n: Int = 3

n == 0在做时,在doSomething函数中

for (entry <- rs if (entry._1 == d)) yield entry._2
//res0: List[Int] = List(2)

您会看到返回类型为List[Int]

对于其他部分,您将递归调用doSomething。

我已经创建了您的虚拟doSomething方法,因为您的doSomething函数定义缺少输入变量,因为

 def dosomething(nn: Int)={
  for (entry <- rs if (entry._1 == d)) yield entry._2
}

并且我以

的方式递归调用该方法
for (entry <- rs; adj <- als(entry._1)) yield dosomething(0)
//res1: List[List[Int]] = List(List(2), List(2), List(2), List(2))

很明显,您可以看到第二个嵌套的for循环返回List[List[Int]]

多数民众赞成在编译器警告您

  

error: type mismatch; found : List[List[Int]] required: List[Int]

我希望答案会有所帮助