3

I was writing a simple application using Scala and I noticed a pretty strange behaviour. I was able to call the contains method of a String class and pass any object to it. Here's a simple code to illustrate it. I used a worksheet and I don't think there is any need to write a main method since it's irrelevant.

class Man
val m = new Man
"hello".contains(m)

I was quite surprised that Scala compiler didn't complain and returned false. So I've decided to look into the contains a bit more thoroughly.

First, the String class itself doesn't have the contains method. It's located in the StringOps class, to which, as far as I know, String can be implicitly converted. The method looks like this in Scala 2.11 docs:

def contains[A1 >: Char](elem: A1): Boolean

Tests whether this sequence contains a given value as an element.

Therefore, as I understand the type bounds, the elem must be of a supertype of a Char. The question is, how can this be, that the Man class is a supertype of a Char? Is there any implicit conversion? I've noticed that 2.10 Scala docs contain another definition of contains:

def contains(elem: Any): Boolean Tests whether this string contains a given value as an element.

This method looks pretty logical for me, since Man class is clearly Any as well. However, the most recent documentation I've found contains the definition I provided earlier.

Vlad Stryapko
  • 1,035
  • 11
  • 29
  • I cannot reproduce your claim with Scala 2.11.6 with which "hello".contains(m) evaluates to False in the REPL. –  Jul 13 '15 at 13:46
  • 1
    Well, I've never stated it would give a 'true'. The issue was not with it. – Vlad Stryapko Jul 13 '15 at 13:53
  • Thank you, I think it pretty much explains the behaviour. For some reason, I wasn't able to find any answers, albeit I did try. – Vlad Stryapko Jul 13 '15 at 14:58

1 Answers1

4

StringOps extends StringLike which extends IndexedSeqOptimized[Char, String] which is covariant in the element type. This means you can do this:

val s: IndexedSeqOptimized[Any, String] = "hello"

This means you can provide an instance of Any to contains, which m is.

Lee
  • 142,018
  • 20
  • 234
  • 287