title: Example of contravariance
body: <p>I am thinking of the following example to illustrate why contravariance is useful.</p>
  
  <p>Let's consider a GUI framework with <code>Widgets</code>, <code>Events</code>, and <code>Event Listeners</code>.</p>
  
  <pre><code>abstract class Event;
  class KeyEvent extends Event
  class MouseEvent extends Event
  
  trait EventListener[-E] { def listen(e:E) }</code></pre>
  
  <p>Let <code>Widgets</code> define the following methods:</p>
  
  <pre><code>def addKeyEventListener(listener:EventListener[KeyEvent])
  def addMouseEventListener(listener:EventListener[MouseEvent])
  </code></pre> 
  
  <p>These methods accept only "specific" event listeners, which is fine. However I would like to define also "kitchen-sink" listeners, which listen to all events, and pass such listeners to the "add listener" methods above. </p>
  
  <p>For instance, I would like to define <code>LogEventListener</code> to log all incoming events</p>
  
  <pre><code>class LogEventListener extends EventListener[Event] {
     def listen(e:Event) { log(event) }
  }</code></pre>
  
  <p>Since the trait <code>EventListener</code> is <em>contravariant</em> in <code>Event</code> we can pass <code>LogEventListener</code> to all those "add listener" methods without losing their type safety.</p>
  
  <p>Does it make sense ?</p>