Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Well, simple, does it make sense? Think of Liskov substitution.</p> <h2>Co-variance</h2> <p>If <code>A &lt;: B</code>, does it make sense to pass a <code>C[A]</code> where a <code>C[B]</code> is expected? If so, make it <code>C[+T]</code>. The classic example is the immutable <code>List</code>, where a <code>List[A]</code> can be passed to anything expecting a <code>List[B]</code>, assuming <code>A</code> is a subtype of <code>B</code>.</p> <p>Two counter examples:</p> <p>Mutable sequences are invariant, because it is possible to have type safety violations otherwise (in fact, Java's co-variant <code>Array</code> is vulnerable to just such things, which is why it is invariant in Scala).</p> <p>Immutable <code>Set</code> is invariant, even though its methods are very similar to those of an immutable <code>Seq</code>. The difference lies with <code>contains</code>, which is typed on sets and untyped (ie, accept <code>Any</code>) on sequences. So, even though it would otherwise be possible to make it co-variant, the desire for an increased type safety on a particular method led to a choice of invariance over co-variance.</p> <h2>Contra-variance</h2> <p>If <code>A &lt;: B</code>, does it make sense to pass a <code>C[B]</code> where a <code>C[A]</code> is expected? If so, make it <code>C[-T]</code>. The classic would-be example is <code>Ordering</code>. While some unrelated technical problems prevent <code>Ordering</code> from being contra-variant, it is intuitive that anything that can order a super-class of <code>A</code> can also order <code>A</code>. It follows that <code>Ordering[B]</code>, which orders all elements of type <code>B</code>, a supertype of <code>A</code>, can be passed to something expecting an <code>Ordering[A]</code>.</p> <p>While Scala's <code>Ordering</code> is not contra-variant, <a href="http://code.google.com/p/scalaz/" rel="noreferrer">Scalaz</a>'s <a href="http://scalaz.googlecode.com/svn/continuous/latest/browse.sxr/scalaz/Order.scala.html" rel="noreferrer">Order</a> is contra-variant as expected. Another example from Scalaz is its <a href="http://scalaz.googlecode.com/svn/continuous/latest/browse.sxr/scalaz/Equal.scala.html" rel="noreferrer">Equal</a> trait.</p> <h2>Mixed Variance?</h2> <p>The most visible example of mixed variance in Scala is <code>Function1</code> (and 2, 3, etc). It is contra-variant in the parameter it receives, and co-variant in what it returns. Note, though, that <code>Function1</code> is what is used for a lot of closures, and closures are used in a lot of places, and these places are usually where Java uses (or would use) Single Abstract Method classes.</p> <p>So, if you have a situation where a SAM class applies, that's likely a place for mixed contra-variance and co-variance.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload