问题描述
我是 Scala 的新手,我想构建一个与对象匹配的小型递归模式。 我在以下代码中不断收到不匹配:
abstract class Fixednode
case class LoopBeginNode(lb: ArrayLengthNode) extends Fixednode
case class ArrayLengthNode(al: Fixednode) extends Fixednode
case class IfNode(i: Fixednode) extends Fixednode
case class BeginNode(b: Fixednode) extends Fixednode
case class Loadindexednode(li: Fixednode) extends Fixednode
case class FixedGuardNode(fg: Fixednode) extends Fixednode
case class EndNode(e: String) extends Fixednode
object HelloWorld {
def main(args: Array[String]) {
println(matchIt(LoopBeginNode(ArrayLengthNode(EndNode("")))))
}
def matchIt(e: Fixednode): String = e match {
case EndNode(en) => "match"
case LoopBeginNode(lb) if lb == ArrayLengthNode(e) => matchIt(lb)
case ArrayLengthNode(al) if al == EndNode("") => matchIt(al)
case IfNode(i) if i == BeginNode(i) => matchIt(i)
case BeginNode(b) if b == EndNode("") =>matchIt(b)
case _ => "No match"
}
}
如果我添加一个简单的 LoopBeginNode(EndNode(""))
,我会得到一个匹配项。虽然在上面更复杂的情况下,我得到了一个不匹配,根据我的理解,它来自 lb
变量,它是一个 EndNode
而在条件中是一个 Fixednode
。你知道我将如何使它工作吗?
最后我想以更复杂的方式结束
ArrayLengthNode(IfNode(BeginNode(Loadindexednode(GuardeElseNode(LoadindexNode(IfNode(EndNode(""))))))))
解决方法
您的模式匹配结构不太正确,请在下面找到更正的:
/**
* Use `sealed` to box type and pattern matching will show compilation warnings.
*/
sealed trait FixedNode
case class LoopBeginNode(lb: ArrayLengthNode) extends FixedNode
case class ArrayLengthNode(al: FixedNode) extends FixedNode
case class IfNode(i: FixedNode) extends FixedNode
case class BeginNode(b: FixedNode) extends FixedNode
case class LoadIndexedNode(li: FixedNode) extends FixedNode
case class FixedGuardNode(fg: FixedNode) extends FixedNode
case class EndNode(e: String) extends FixedNode
object HelloWorld {
def main(args: Array[String]) {
println(matchIt(LoopBeginNode(ArrayLengthNode(EndNode("")))))
//ArrayLengthNode(IfNode(BeginNode(LoadIndexedNode(GuardeElseNode(LoadIndexNode(IfNode(EndNode(""))))))))
}
def matchIt(e: FixedNode): String = e match {
case EndNode(en) => "match"
/**
* In previous version `case LoopBeginNode(lb) if lb == ArrayLengthNode(e) => matchIt(lb)`
* 'lb == ArrayLengthNode(e)' - always false,because you comparing in this case
* `ArrayLengthNode(EndNode("")) == ArrayLengthNode(LoopBeginNode(ArrayLengthNode(EndNode(""))))`
* which is always false.
*
* Same approach used for other patterns
*/
case LoopBeginNode(ArrayLengthNode(lb)) => matchIt(lb)
case ArrayLengthNode(EndNode("")) => "match"
case IfNode(BeginNode(i)) => matchIt(i)
case BeginNode(EndNode("")) => "match"
case _ => s"No match at: `$e`"
}
}
和 Scatie 一起玩:https://scastie.scala-lang.org/zfEd5DprQUKDttLcc6D54w