Классы дел и сопоставление с образцом в списке - PullRequest
4 голосов
/ 08 февраля 2012

Я хотел бы упростить это выражение

Opt (Opt (ExpList (List ( Opt (Opt (Var ( "опция")))))))

чтобы получить что-то подобное

Опт (ExpList (Список ( Опт (Var ( "опция")))))


Как будет выглядеть выражение, чтобы упростить все выражения внутри списка.

Каковы лучшие практики для таких задач?

Фрагмент кода, который я пробовал, таков:

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]

Для тех из вас, кому интересно, похожая тема:

Классы дел Scala, сопоставление с образцом и переменные

Ответы [ 2 ]

7 голосов
/ 08 февраля 2012

Вам нужно четыре случая:

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
}
3 голосов
/ 08 февраля 2012

Ну, я бы написал joinOpt так:

def joinOpt(feature: Expr): Expr = feature match {
  case Opt(Opt(f))   => joinOpt(Opt(f))    // Opt(Opt("test")) --> Opt("test")
  case ExpList(list) => ExpList(list map joinOpt)
  case other         => other
}
...