Singleton type not inferred correctly
Closed this issue · 4 comments
This modified example from SI-5103 fails to compile:
$ curl -s https://raw.githubusercontent.com/typelevel/scala/typelevel-readme/try-typelevel-scala.sh | bash
Loading...
Welcome to the Ammonite Repl 0.8.4
(Scala 2.12.2-bin-typelevel-4 Java 1.8.0_112)
If you like Ammonite, please support our development at www.patreon.com/lihaoyi
@ repl.compiler.settings.YliteralTypes.value = true
@ val x = "one"
x: String = "one"
@ def single[T <: String with Singleton](x: T) = x
defined function single
@ single(x)
cmd3.sc:1: inferred type arguments [String] do not conform to method single's type parameter bounds [T <: String with Singleton]
val res3 = single(x)
^
cmd3.sc:1: type mismatch;
found : String
required: T
val res3 = single(x)
^
Compilation Failed
That's the expected behaviour.
If you want a val to have an inferred singleton type it should be marked as final. This is consistent between Typelevel and Lightbend Scala.
Thanks! Adding final
fixes this particular example. Unfortunately, final val
s cannot be used within function definitions.
Do you have any insights as to why val
s cannot be inferred when the singleton type is String with Singleton
as opposed to Singleton
?
You can give the def a literal result type. Bear in mind that a literal type as a result means that the method must be constant so there's no reason (other than side effects, tsk, tsk) not to use a final val here, which might also be inlined.
@tindzk This is one of the reasons I created TwoFace
values in the singleton-ops library. They keep their 'final-ness' as long as possible.
https://contributors.scala-lang.org/t/twoface-values-closing-the-gap-between-run-compile-time-functionality/869