У меня есть древовидная структура абстрактных классов и case-классов, представляющих абстрактное синтаксическое дерево небольшого языка.
Для верхнего абстрактного класса я реализовал метод map
:
abstract class AST {
...
def map(f: (AST => AST)): AST = {
val b1 = this match {
case s: STRUCTURAL => s.smap(f) // structural node for example IF(expr,truebranch,falsebranch)
case _ => this // leaf, // leaf, like ASSIGN(x,2)
}
f(b1)
}
...
Smap определяется как:
override def smap(f: AST => AST) = {
this.copy(trueb = trueb.map(f), falseb = falseb.map(f))
}
Теперь я пишу различные «преобразования» для вставки, удаления и изменения узлов в AST.
Например, удалить соседние узлы NOP из блоков:
def handle_list(l:List[AST]) = l match {
case (NOP::NOP::tl) => handle_list(tl)
case h::tl => h::handle_list(tl)
case Nil => Nil
}
ast.map {
case BLOCK(listofstatements) => handle_list(listofstatements)
}
Если я напишу так, я получу MatchError
, и я смогу "исправить это", изменив приведенную выше карту на:
ast.map {
case BLOCK(listofstatements) => handle_list(listofstatements)
case a => a
}
Должен ли я просто жить со всеми этими case a => a
или я мог бы каким-то образом улучшить свой метод map
(или другие части)?