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?

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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.
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.
You are right @AlexeyRomanov, I will only keep BinaryStringPerceptualHash with implementation and create class / object extending it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.