scala - 一个“简单”的 Scala 问题,但我花了很长时间来调试
问题描述
请检查上面的两段脚本。
genComb4(lst)
自从我在理解z <- genComb4(xs)
之前开始工作;不起作用,因为我为了理解而更改了这两行的顺序。i <- 0 to x._2
genComb(lst)
我花了将近半天的时间才找到这个错误,但我无法自己解释。你能告诉我为什么会这样吗?
非常感谢您提前。
// generate combinations
val nums = Vector(1, 2, 3)
val strs = Vector('a', 'b', 'c')
val lst: List[(Char, Int)] = strs.zip(nums).toList
def genComb4(lst: List[(Char, Int)]): List[List[(Char, Int)]] = lst match {
case Nil => List(List())
case x :: xs =>
for {
z <- genComb4(xs) // correct
i <- 0 to x._2 // correct
} yield ( (x._1, i) :: z)
}
genComb4(lst)
def genComb(lst: List[(Char, Int)]): List[List[(Char, Int)]] = lst match {
case Nil => List(List())
case x :: xs =>
for {
i <- (0 to x._2) // wrong
z <- genComb(xs) // wrong
} yield ( (x._1, i) :: z)
}
genComb(lst)
解决方案
这是因为for comprehension
. 当您for-comprehension
从 line:开始时,i <- (0 to x._2)
将结果容器的类型设置为IndexedSeq
但如果第一行是z <- genComb4(xs)
结果容器的类型,List
请看一下:
val x = 'a' -> 2
val indices: Seq[Int] = 0 to x._2
val combs: List[List[(Char, Int)]] = genComb4(List(x))
// indexed sequence
val indicesInFor: IndexedSeq[(Char, Int)] = for {
i <- 0 to x._2
} yield (x._1, i)
// list
val combsInFor: List[List[(Char, Int)]] = for {
z <- genComb4(List(x))
} yield z
所以为了让你的第二种情况有效,你应该投(0 to x._2).toList
:
val indicesListInFor: List[(Char, Int)] = for {
i <- (0 to x._2).toList
} yield (x._1, i)
结果代码应为:
def genComb(lst: List[(Char, Int)]): List[List[(Char, Int)]] = lst match {
case Nil => List(List())
case x :: xs =>
for {
i <- (0 to x._2).toList
z <- genComb(xs)
} yield ( (x._1, i) :: z)
}
genComb(lst)
您应该记住scala 集合的理解和继承中的起始线类型。如果继承规则不能将下一个类型转换为第一个表达式行类型,您应该自己处理它。for-comprehension
好的做法是打开for-expression
,flatMap
和map
函数withFilter
,然后你会发现输入错误或其他更快的东西。
有用的链接:
推荐阅读
- angular - 检查数组的子元素
- azure - 如何将 Azure AKS Kubernetes 集群自签名 CA 添加到 GitLab CI/CD Kubernetes 集成?
- swift - 无法获取从 dataTask() 返回的数据
- r - 如何在R中按组减去三个观察值的中位数
- spring - Spring Could not open Hibernate Session for transaction. Unable to acquire JDBC Connection
- c++ - auto, template? How to construct method returning different datatypes
- copy - 有没有办法在 pentaho 报表设计器中复制整个报表?
- java - Java Power function answers
- rust - 如何有条件地在结构的两个字段之间进行选择,然后更新选择的字段?
- botframework - 重命名我的解决方案后,Bot Framework 模拟器未发布到本地主机(500 错误)