1

As far as I understand, in Scala

String is an alias for java.lang.String

as explained here, and can be seen in Predef.scala:

type String = java.lang.String

So essentially, they are the same.

However, in IntelliJ IDEA 2017.2.5, the below code produces an error:

trait PerceptualHash {
  def calc[A](bi: BufferedImage): A
}

sealed trait BinaryStringPerceptualHash extends PerceptualHash {
  override def calc[String](bi: BufferedImage): String
}

private object GeneralBinaryStringPerceptualHash extends BinaryStringPerceptualHash {
  def calc[String](bi: BufferedImage): String = "0"
}

Here, "0" gets underlined with message "Expression of type java.lang.String does not conform to expected type String".

But if I change "0" like so:

def calc[String](bi: BufferedImage): String = new String("0")

then I get no such error message.

What's going on? Is it expected behaviour (and if so, why), am I doing something wrong, or rather it is a type inference bug in Intellij IDEA?

parazs
  • 43
  • 3

1 Answers1

2

Your signature for calc says that a PerceptualHash can convert a BufferedImage to any type the caller asks for. E.g. it's legal to do

GeneralBinaryStringPerceptualHash.calc[Int](image)

So String in

def calc[String](bi: BufferedImage): String = "0"

is just the name you gave to a parameter, unrelated to the standard String type. It is the same as

def calc[A](bi: BufferedImage): A = "0"

But if I change "0" like so:

def calc[String](bi: BufferedImage): String = new String("0")

then I get no such error message.

You should get a different error message but you should still get one.

You probably want

trait PerceptualHash[A] {
  def calc(bi: BufferedImage): A
}

// calc is already def calc(bi: BufferedImage): String here, no need to override
sealed trait BinaryStringPerceptualHash extends PerceptualHash[String]

instead.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • It is indeed what I want, thank you. And your comment about the uselessness of overriding `calc` in `BinaryStringPerceptualHash` blows my mind :-) Such is the power of type parameterisation. – parazs Nov 04 '17 at 15:14
  • I'd add that `BinaryStringPerceptualHash` is not itself particularly useful unless either 1) it has some shared code or 2) you need to test whether some `PerceptualHash` is a `BinaryStringPerceptualHash`. – Alexey Romanov Nov 04 '17 at 17:22
  • You are right @AlexeyRomanov, I will only keep `BinaryStringPerceptualHash` with implementation and create class / object extending it. – parazs Nov 04 '17 at 21:19