This page is no longer maintained — Please continue to the home page at www.scala-lang.org

concrete motivations for contravariance

No replies
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.

I went back to my Numeric transformation code and polished it up. Here
is an example which creates "Option math":

import Numeric.{ Transforms, Zero }

val mybijec = new Transforms[Int, Option[Int]](
{ case x: Int => Some(x) },
{ case x: Option[Int] if x.isDefined => x.get }
)(zeroU = Zero(None))

implicit val n = Numeric[Int] on mybijec

Now I can do this:

scala> (1 to 10) map Some[Int] sum
:8: error: could not find implicit value for parameter num: Numeric[Some[Int]]
(1 to 10) map Some[Int] sum
^

Oh wait, no I can't because Numeric is not contravariant and the
inferred type is Seq[Some[Int]]. I have to do this:

scala> ((1 to 10) map Some[Int] : Seq[Option[Int]]) sum
res1: Option[Int] = Some(55)

Here is a similar situation for Ordering.

scala> def cmp[T](x1: T, x2: T)(implicit ord: Ordering[T]) = ord.lt(x1, x2)
cmp: [T](x1: T,x2: T)(implicit ord: Ordering[T])Boolean

scala> cmp(Some(5), Some(10))
:6: error: type arguments [Some[Int]] do not conform to method ordered's type parameter bounds [A <: Ordered[A]]
cmp(Some(5), Some(10))
^

scala> cmp(Some(5): Option[Int], Some(10))
res2: Boolean = true

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland