title: Scala pattern match agains object in trait
body: <p>I have a trait containing multiple case classes and objects for example:</p>
  
  <pre><code>trait Logic[A &lt;: Logic[A]] {
     case class And(l: Logic[A], l2: Logic[A]) extends Logic[A]
     trait Atom extends Logic[A]
     case object True extends Atom
     case object False extends Atom
   //  ...
  }
  
  trait LTLLogic extends Logic[LTLLogic]
  object LTLLogic extends Logic[LTLLogic]
  </code></pre>
  
  <p>Now I want to match against a formula of type <code>Logic[A]</code>.</p>
  
  <pre><code>class Matcher[A &lt;: Logic[A]] {
  
   def matchFormula(f: Logic[A]) = f match {
     case a: Logic[A]#And =&gt; //do something
     case Logic[A]#True =&gt; //&lt;&lt; not working
     case Logic[A]#False =&gt; //&lt;&lt; not working
     case _ =&gt; //other cases
   }
  
  }
  </code></pre>
  
  <p>The problem is, matching against <code>Logic[A]#And</code> is working fine but I can't match against <code>True</code> and <code>False</code>. I could probably get it working if I match against the classes:</p>
  
  <pre><code>   case a:Logic[A]#Atom if a.getClass == a.True.getClass =&gt; //do something
     case a:Logic[A]#Atom if a.getClass == a.False.getClass =&gt; //do something
  </code></pre>
  
  <p>but I don't really like this solution. Is there any other way to make it working?</p>
  
  <hr>
  
  <p>It looks like path-dependent types were not the right tool for this.
  Moving the case classes/objects, as suggested, out of the <code>trait</code> into an <code>object Logic</code> and making <code>A</code> in Logic covariant seems to be working.</p>
  
  <pre><code>trait Logic[+A &lt;: Logic[A]]
  object Logic{
     case class And[A &lt;: Logic[A]](l: Logic[A], l2: Logic[A]) extends Logic[A]
     trait Atom[A &lt;: Logic[A]] extends Logic[A]
     case object True extends Atom[Nothing]
     case object False extends Atom[Nothing]
  }
  </code></pre>