Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
497 views
in Technique[技术] by (71.8m points)

pattern matching - Scala match recursive objects

I am a newbie in Scala and I want to build a small recursive pattern matching with objects. I keep getting a No match in the following code:

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"
    }
   }

If I add a simple LoopBeginNode(EndNode("")) I get a match. Although in the more complex case above I get a mismatch, which according to my understanding, comes from the lb variable which is an EndNode whereas in the condition is a FixedNode. Do you have any idea how I am going to make it work? I want in the end to conclude in something more complex like

ArrayLengthNode(IfNode(BeginNode(LoadIndexedNode(GuardeElseNode(LoadIndexNode(IfNode(EndNode(""))))))))
question from:https://stackoverflow.com/questions/65924782/scala-match-recursive-objects

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your pattern matching construction was not really correct, please find fixed one below:

/**
* 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`"
    }
}

And Scatie to play with it: https://scastie.scala-lang.org/zfEd5DprQUKDttLcc6D54w


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...