Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case Classes and Pattern Matching on List

What I would like to do is simplify this expression

Opt(Opt(ExpList(List(Opt(Opt(Var("optional")))))))

to get something like that

Opt(ExpList(List(Opt(Var("optional")))))


What would match expression look like in order to simplify all expressions inside the list.

What are best-practises for those kind of tasks?

The code snippet I tried is this:

object CaseClassPatternMatching extends App {
  abstract class Expr
  case class Var(name: String) extends Expr
  case class Opt(expr: Expr) extends Expr
  case class ExpList(listExp: List[Expr]) extends Expr

  def joinOpt(feature: Expr): Expr = feature match {
    case Opt(Opt(f)) => joinOpt(Opt(f))    // Opt(Opt("test")) --> Opt("test")
    // case ExpList(list) => ????          // What to do there?
    case _ => feature
  }

  val expr1: Expr = joinOpt(Opt(Opt(Opt(Var("optional")))))
  println(Opt(Var("optional"))) 
  // Output: Opt(Var(optional))  --> That one is OK...

  val expr2: Expr = joinOpt(Opt(Opt(ExpList(List(Opt(Opt(Var("optional"))))))))
  println(expr2)
  // Output: Opt(ExpList(List(Opt(Opt(Var(optional))))))  --> Not OK...
  // How to simplify expressions inside list?
}

[EDIT]

For those of you who are interested, similar topic:

Scala case classes, pattern matching and varargs

like image 296
PrimosK Avatar asked Dec 27 '22 06:12

PrimosK


1 Answers

You need four cases:

def joinOpt(feature: Expr): Expr = feature match {
                         // remove extra Opt 
                         // (you can use @ to avoid recreating Opt)
  case Opt(opt @ Opt(_)) => joinOpt(opt) 
                         // preserve single Opt
  case Opt(expr)         => Opt(joinOpt(expr)) 
                         // apply function to all elements in inner list
  case ExpList(list)     => ExpList(list map joinOpt) 
  case _ => feature
}
like image 91
incrop Avatar answered Jan 08 '23 10:01

incrop