Why does the last summon fails to compile? What can I do to make it compile?
import java.time.{LocalDateTime, LocalTime}
trait Circular[T]:
type Parent
given localTimeCircular: Circular[LocalTime] with
type Parent = LocalDateTime
final class CircularMap[K, +V]()(using val circular: Circular[K])
val summoned = summon[Circular[LocalTime]]
val daily = new CircularMap[LocalTime, Int]()
println(summoned == daily.circular) // Prints true
summon[localTimeCircular.Parent =:= LocalDateTime]
summon[summoned.Parent =:= LocalDateTime]
summon[daily.circular.Parent =:= LocalDateTime]
It fails on Scala 3.0.2 and 3.1.0-RC1
The thing is not in Scala 3. In Scala 2.13.6 simlar code doesn't compile
https://scastie.scala-lang.org/DmytroMitin/lsX3fS3ET0ajzChwl2Mctw
(I replaced
implicitlywiththein one place becauseimplicitlycan break type refinements,summonis more likethe).Let's simplify your code in order to figure out what's going on. Let's remove implicits (let's resolve them explicitly)
The thing is that path-dependent types are designed so that even if
x == x1it's not necessary thatx.T =:= x1.TIn the latest release of scala (2.12.x), is the implementation of path-dependent type incomplete?
Force dependent types resolution for implicit calls
How to create an instances for typeclass with dependent type using shapeless
It's true that
summoned == daily.circularbutsummonedhas typeCircular[LocalTime] { type Parent = LocalDateTime }whiledaily.circularhas typeCircular[LocalTime]. You specified it so:val circular: Circular[K]. So you upcasted refined typeCircular[LocalTime] { type Parent = LocalDateTime }(let's denote itCircular.Aux[LocalTime, LocalDateTime]) to its supertype, namely the type without refinementCircular[LocalTime](aka existential typeCircular.Aux[LocalTime, _]). So typeslocalTimeCircular.Parentandsummoned.ParentareLocalDateTimebut typedaily.circular.Parentis abstract. If you want to restore type refinement for example you can defineAnother way is to use singleton type
What you want is actually multiple type parameter lists on class (so that in
class CircularMap[K, +V][P]you can specifyK,Vand inferP)https://github.com/scala/bug/issues/4719
https://contributors.scala-lang.org/t/multiple-type-parameter-lists-in-dotty-si-4719/2399
You can emulate them