Why does Iterator have a contains method but Iterable does not, in Scala 2.8?

前端 未结 2 344
忘了有多久
忘了有多久 2020-12-10 12:38

I would like to call \'contains\' on my Iterables :-)

相关标签:
2条回答
  • 2020-12-10 12:42

    The reason Iterable does not have a contains method is because the way it is defined can have direct consequences on variance. Basically, there are two type signatures that make sense for it:

    def contains(v: Any): Boolean
    def contains(v: A): Boolean
    

    The second definition has increased type safety. However, A, which is the type parameter of collection, appears in a contra-variant position, which forces the collection to be invariant. It could be defined like this:

    def contains[B >: A](v: B): Boolean
    

    but that wouldn't offer any improvement over the first signature, using Any.

    As a consequence of this, you'll see that immutable.Seq is co-variant and uses the first signature, while immutable.Set is invariant and uses the second signature.

    0 讨论(0)
  • 2020-12-10 12:51

    I don't know why contains is not defined on Iterable or TraversableOnce, but you could easily define it yourself:

    class TraversableWithContains[A](underlying: TraversableOnce[A]) {
      def contains(v: Any): Boolean =
        underlying.exists(_ == v)
    }
    implicit def addContains[A](i: Iterable[A]) = new TraversableWithContains(i)
    

    and use it as if it were defined on Iterable:

    val iterable: Iterable[Int] = 1 to 4
    assert(iterable.contains(3))
    assert(!iterable.contains(5))
    
    0 讨论(0)
提交回复
热议问题