While debugging my program, I found that I had made the mistake of supplying the wrong argument to the containsSlice
method of a Seq[Char]
. I had supplied a Seq[Boolean]
which is of course never contained in the Seq[Char]
.
Why did the compiler let me do this? Can't this method be implemented in a type-safe way in the Scala collections library? I think it must have been done deliberately to be able to supply a Seq[Any]
, which could theoretically be all Char
s. But shouldn't the designers have kept this method type-safe and add some non-type-safe method like containsAnySlice
?
EDIT:
I've tried creating my own type-safe containsSlice
method outside of the collection class hierarchy, but for some reason the code in the test
method compiles while I had hoped it wouldn't:
object Seqs {
def containsSlice[A, B <: A](s1: Seq[A], s2: Seq[B]): Boolean = {
s1.containsSlice(s2)
}
def test = {
val sc: Seq[Char] = Seq('A','B','C')
val sb: Seq[Boolean] = Seq(true, false)
containsSlice(sc, sb)
}
}
I guess this is because the common supertype of Char
and Boolean
(AnyVal
) is inferred for type parameter A
, and I need to explicitly call containsSlice[Char](sc, sb)
if I don't want that (but then I could just use sc.containsSlice[Char](sb)
).
To make it not compile for incompatible Seq
s, the only way I could do this is use 2 parameter lists so the correct type gets inferred:
object Seqs {
def containsSlice[A, B <: A](s1: Seq[A])(s2: Seq[B]): Boolean = {
s1.containsSlice(s2)
}
def test = {
val sc: Seq[Char] = Seq('A','B','C')
val sb: Seq[Boolean] = Seq(true, false)
containsSlice(sc)(sb) // does not compile, yay!
}
}