假定以下的數據結構。提高模式匹配代碼
sealed abstract class Formula {...}
//... some other case classes
sealed abstract class BinaryConnective(f0: Formula, f1: Formula) extends Formula {
def getf0 = f0
def getf1 = f1
}
object BinaryConnective {
def unapply(bc : BinaryConnective) = Some((bc.getf0, bc.getf1))
}
final case class Conjunction(f0: Formula, f1: Formula) extends BinaryConnective(f0,f1)
final case class Disjunction(f0: Formula, f1: Formula) extends BinaryConnective(f0,f1)
final case class Implication(f0: Formula, f1: Formula) extends BinaryConnective(f0,f1)
final case class Equivalence(f0: Formula, f1: Formula) extends BinaryConnective(f0,f1)
我現在寫的,有很多模式匹配的功能:
返回型getCondition
是Formula => Option[HashMap[Variable, Formula]]
formula match {
//.. irrelevant cases not shown
case Conjunction(f0, f1) => (g : Formula) => {
g match {
case conj @ Conjunction(g0, g1) => {
getCondition(f0)(conj.f0) match {
case Some(map0) => {
getCondition(f1)(conj.f1) match {
case Some(map1) if map0.forall{case (key, value) => map1.get(key).map(_ == value).getOrElse(true)} => {
Some(map0 ++ map1)
}
case _ => None
}
}
case None => None
}
}
case _ => None
}
}
}
現在我的問題。
1)是否有表達這種代碼更好的方式?很多比賽正在進行中。
編輯1:我想不出來使用的東西像map
,filter
等。一個看上去不錯的方式,但它似乎很緊湊,換內涵。我也注意到,conj @
根本就沒有必要,這也使得它更簡單一些。
case Conjunction(f0, f1) => (g: Formula) => g match {
case Conjunction(g0, g1) => for {
map0 <- getCondition(f0)(g0)
map1 <- getCondition(f1)(g1)
if map0.forall {case (key, value) => map1.get(key).map(_ == value).getOrElse(true)}
} yield map0 ++ map1
case _ => None
}
2)這是匹配Conjunction
。我將不得不重複它Disjunction
,Implication
和Equivalence
。 g
必須是同一類formula
的。唯一會改變的是case conj @ Conjunction(g0, g1)
。我將不得不將其調整到case disj @ Disjunction(g0, g1)
如果formula
是一個選言等... 有沒有辦法做到這一點相結合的所有情況?
對於2),I可如果代碼真的是完全相同的,那麼你會不會使用父類? 'case BinaryConnenective(g0,g1)'? –
是的,我可以匹配'BinaryConnnective'。但如果我在'BinaryConnnective'上的'公式'和'BinaryConnenective'上的'g'匹配,我怎樣才能確保它們都是'Conjunction'或者都是'Disjunction'等。 – Kigyo