为什么打印wtf?模式匹配不适用于结构类型吗?
"hello" match {
case s: { def doesNotExist(i: Int, x: List[_]): Double } => println("wtf?")
case _ => println("okie dokie")
}
Run Code Online (Sandbox Code Playgroud) 你总是可以构建一个递归函数来消除尾部调用吗?如果没有,那么限制堆栈大小的其他策略是什么?
例如:(灵感来自Break或shortcircuit Scala中的折叠)
// Depth-first search of labyrinth, with large depth > stacklimit
def search ( labyrinth: SearchDomain,
path: List[SolutionNode],
goal: DesiredResult ) = {
if ( path.head == goal ) return path
candidates: List[SolutionNode] = labyrinth.childNodes(path)
candidates.find { c =>
Nil != search( labyrinth, c :: path, goal ) // potential boom!
} match {
case Some(c) => c :: path
case None => Nil
}
}
Run Code Online (Sandbox Code Playgroud)
我们的目标不是挑选这个特定的功能,而是将其用作学习限制堆栈大小的技术.
UPDATE
我从中得到的结论是:
如果问题域是递归可能会达到堆栈大小的限制:
将代码重写为scala-compiler-version-of-tailcall-optimizable.这可以通过新的(2.8)@scala.annotation.tailrec注释来辅助/验证.
如果这不可行,请将其重写为使用迭代循环结构.
我也感觉到这种重写(任何一种情况)都需要一定的技能/才能/智慧/练习.
在Scala(Specs,ScalaTest,ScalaCheck)中有一些很好的库可供测试.但是,使用Scala强大的类型系统,在Scala中开发的API的重要部分是静态表达的,通常以编译器阻止某些不受欢迎或不允许的行为的形式表示.
那么,在设计库或其他API时,测试编译器是否阻止某些内容的最佳方法是什么?注释掉应该是不可编译的代码然后取消注释以进行验证是不令人满意的.
一个人为的例子测试列表:
val list: List[Int] = List(1, 2, 3)
// should not compile
// list.add("Chicka-Chicka-Boom-Boom")
Run Code Online (Sandbox Code Playgroud)
其中一个现有的测试库是否处理这样的情况?是否存在人们使用的方法?
我正在考虑的方法是将代码嵌入到三引号字符串或xml元素中,并在我的测试中调用编译器.调用代码看起来像这样:
should {
notCompile(<code>
val list: List[Int] = List(1, 2, 3)
list.add("Chicka-Chicka-Boom-Boom")
</code>)
}
Run Code Online (Sandbox Code Playgroud)
或者,在解释器上调用期望类型脚本.