Aymen
Aymen

Reputation: 558

Structural types and primitives

I was playing around with Scala's structural types when I discovered what looks like a bug to me. Here is my code:

type toD = { def toDouble: Double }
def foo(t: toD) = t.toDouble
foo(5)

And I got this error:

java.lang.NoSuchMethodException
at scala.runtime.BoxesRunTime.toDouble(Unknown Source)
at .foo(<console>:9)
at .<init>(<console>:11)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Unknown Source)

First, I don't know why this isn't working. Second, it's weird that the code compiles just fine and throws an exception at runtime saying that the method doesn't actually exist.

Does anyone have an explanation for this?

Upvotes: 5

Views: 241

Answers (1)

drexin
drexin

Reputation: 24413

I just played around a bit with this and it really seems to be a bug. However it works when you just set the return type to Any:

type toD = { def toDouble: Any }

I think it may have something to do with auto boxing and the way primitives are handled.

edit:

I just found a workaround:

type toD[A] = { def toDouble: A }
def foo[A](x: toD[A])(implicit y: A =:= Double) = x.toDouble

This ensures, that the return value of toDouble (A) is Double

Upvotes: 6

Related Questions