假设以下数据结构。
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
等内容的漂亮方式,但是对于for-comprehension看起来非常紧凑。我也注意到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)
是Disjunction等,我必须将其调整为formula
...
有没有办法在所有情况下合并?
答案 0 :(得分:2)
Option
应该提供许多有用的功能来简化代码。
例如,当您写下以下内容时:
o match {
case Some(e) => Some(transform(e))
case _ => None
}
您可以致电map
:o.map(transform)
我还邀请您查看包含条件的案例的filter
函数。
编辑:@ om-nom-nom的好建议:也可以使用理解(实际上它们依赖于map
,flatMap
,filter
等等:)< / p>
for{
e <- o
} yield transform(e)