OK, I'm sorry, I misunderstood your question. Anyway, I tried your code, and it looks pretty interesting, but since I like simplicity, I tried to come up with a simpler solution to your problem.
object Sign { case object Pos extends Sign case object Neg extends Sign case object Zero extends Sign case object Undefined extends Sign case object NonPos extends SignSet(Set(Neg, Zero)) { override def toString = "NonPos" } case object NonNeg extends SignSet(Set(Pos, Zero)) { override def toString = "NonNeg" } case object NonZero extends SignSet(Set(Pos, Neg)) { override def toString = "NonZero" } case object AnySign extends SignSet(Set(Pos, Neg, Zero)) { override def toString = "AnySign" } private val signs = List(Pos, Neg, Zero, Undefined, NonPos, NonNeg, NonZero, AnySign) private def calc(op: Symbol, s1: Sign, s2: Sign): Sign = { val sign = _calc(op, s1, s2) signs.find(_ == sign).getOrElse(sign) } private def _calc(op: Symbol, s1: Sign, s2: Sign): Sign = (op, s1, s2) match { case (op, set: SignSet, sign) => set.flatMap(s => _calc(op, s, sign)) case (op, sign, set: SignSet) => set.flatMap(s => _calc(op, sign, s)) case (_, Undefined, _) => Undefined case (_, _, Undefined) => Undefined case ('+, x, y) if x == y => x case ('+, x, Zero) => x case ('+, Zero, x) => x case ('+, Pos, Neg) => SignSet(Pos, Neg, Zero) case ('+, Neg, Pos) => SignSet(Pos, Neg, Zero) case ('-, x, Neg) => _calc('+, x, Pos) case ('-, x, Pos) => _calc('+, x, Neg) case ('-, x, Zero) => x case ('*, Zero, _) => Zero case ('*, Pos, x) => x case ('*, Neg, Pos) => Neg case ('*, Neg, Neg) => Pos case ('*, Neg, Zero) => Zero case ('/, _, Zero) => Undefined case ('/, x, y) => _calc('*, x, y) } } sealed trait Sign { import Sign.calc def +(other: Sign) = calc('+, this, other) def -(other: Sign) = calc('-, this, other) def *(other: Sign) = calc('*, this, other) def /(other: Sign) = calc('/, this, other) def flatten: Sign = this def |(other: Sign): Sign = other match { case sign if sign == this => this case SignSet(signs) => SignSet(signs + this) case sign => SignSet(this, sign) } } object SignSet { def apply(signs: Set[Sign]) = new SignSet(signs) def apply(signs: Sign*) = new SignSet(signs.toSet) def unapply(set: SignSet) = Some(set.signs) } class SignSet(val signs: Set[Sign]) extends Sign { def flatMap(f: Sign => Sign) = SignSet(signs.map(f)).flatten override def flatten = signs.map(_.flatten).reduce(_ | _) override def |(other: Sign) = other match { case SignSet(otherSigns) => SignSet(otherSigns | signs) case sign => SignSet(signs + sign) } override def toString = signs.mkString("SignSet(", ", ", ")") def equals(other: SignSet) = signs == other.signs override def equals(other: Any) = other match { case set: SignSet => equals(set) case _ => false } } import Sign._ println(Pos / NonPos) println(Pos + Neg) println(NonZero * Zero) println(NonZero / NonPos) println(NonZero - NonZero) println(NonZero + Zero)