10 Feb 23:07
scare-quoted "type-safe" contains method for covariant collections
Paul Phillips <paulp <at> improving.org>
2012-02-10 22:07:08 GMT
2012-02-10 22:07:08 GMT
class MyCovariantCollection[+T, +CC[X] <: Seq[X]](xs: CC[T]) {
// Oops, our "evidence" seems to be useless, as what we want
// to know is that T1 <:< T, but of course we can't do that because
// of the variance position.
def contains[T1](x: T1)(implicit ev: T <:< T1): Boolean = xs contains x
}
// But wait! Unspecified implementation vagaries to the rescue!
object Test extends App {
val xs = new MyCovariantCollection(List(1, 2, 3))
assert(xs contains "abc", "I'm sure it's in there somewhere")
}
// Thank-you type inference algorithm! Pick the most specific
// type while resolving the first parameter list without regard
// for the fact that we are doomed once you see the second
// parameter list. That's what we want today.
% scalac ./covariance-contains.scala
./covariance-contains.scala:11: error: Cannot prove that Int <:< java.lang.String.
assert(xs contains "abc", "I'm sure it's in there somewhere")
^
one error found
/*
Yes, of course this works:
xs.contains[Any]("abc")
I don't know about you guys but people going that far out of their way
to look for Strings in a list of Ints is not my most pressing concern.
*/
On Fri, Feb 10, 2012 at 20:07, Paul Phillips <paulp <at> improving.org> wrote:
> class MyCovariantCollection[+T, +CC[X] <: Seq[X]](xs: CC[T]) {
> // Oops, our "evidence" seems to be useless, as what we want
> // to know is that T1 <:< T, but of course we can't do that because
> // of the variance position.
> def contains[T1](x: T1)(implicit ev: T <:< T1): Boolean = xs contains x
> }
>
> // But wait! Unspecified implementation vagaries to the rescue!
> object Test extends App {
> val xs = new MyCovariantCollection(List(1, 2, 3))
> assert(xs contains "abc", "I'm sure it's in there somewhere")
> }
>
> // Thank-you type inference algorithm! Pick the most specific
> // type while resolving the first parameter list without regard
> // for the fact that we are doomed once you see the second
> // parameter list. That's what we want today.
> % scalac ./covariance-contains.scala
> ./covariance-contains.scala:11: error: Cannot prove that Int <:<
> java.lang.String.
> assert(xs contains "abc", "I'm sure it's in there somewhere")
> ^
> one error found
>
> /*
> Yes, of course this works:
>
> xs.contains[Any]("abc")
>
> I don't know about you guys but people going that far out of their way
> to look for Strings in a list of Ints is not my most pressing concern.
> */
>
RSS Feed