Open noresttherein opened 1 year ago
can it be encoded without forSome
? not sure whether to label it "fixed in Scala 3", since Scala 3 doesn't have forSome
Apart from the fact that I have no idea how to write a higher kinded wildcard, M[Unit]#Value
is also illegal in Scala 3.
Yeah, I know Scala 3 has no abstract type projection, but Scala 2 has a much worse typer and I can't use F[_]
as a type parameter, because it will not unify the wildcard member type.
AFAIK, it can't be encoded without forSome
. This is the only way in which a type with a type constructor type parameter can be used as a pattern. Sadly, even if I forgo abstract type projection, I don't think a type pattern with a type constructor type parameter can be written at all in Scala 3 without resolving to:
def test[M[O] <: F[O], V](e :E[M, V]) :Unit = e match {
case _ :G[ F @unchecked] =>
}
FWIW, this is how it could be written in Scala 3:
trait F[O] { type Value }
trait B { type Value }
type TB[V] = B { type Value = V }
trait E extends B { val f :Cons[Unit]; type Cons[O] <: F[O] }
type TE[M[O] <: F[O], V] = E { type Cons[O] = M[O]; type Value = V }
trait G extends E { val f :Cons[Unit]; type Value = f.Value; def get :Value }
type TG[M[O] <: F[O]] = G { type Cons[O] = M[O] }
def test[M[O] <: F[O], V](e :TE[M, V]) :Unit = (e :E) match {
case _ :G =>
}
Edit: it used to be that this did not compile in Scala 2 a couple of years back, so I was forced to use type projections:
trait F[O] { type Value }
trait B { type Value }
type TB[V] = B { type Value = V }
trait E extends B { val f :Cons[Unit]; type Cons[O] <: F[O] }
type TE[M[O] <: F[O], V] = E { type Cons[O] = M[O]; type Value = V }
trait G extends E { val f :Cons[Unit]; type Value = f.Value; def get :Value }
type TG[M[O] <: F[O]] = G { type Cons[O] = M[O] }
trait FF[O] extends F[O] { type Value = Int }
val g :TG[FF] = new G { type Cons[O] = FF[O]; val f = new FF[Unit] {}; def get = 0 }
def test2[M[O] <: F[O]](g :TG[M]) :g.Value = g.get
val notAnInt = test2(g)
notAnInt :Int
Now it seems it is fixed, or I misremember the problem. If it's the former, then great, my migration to Scala 3 will be much easier if I first rewrite everything in Scala 2 to the above.
Unification in Scala 2.13 did get better over the years so it sounds plausible to me that it got fixed (I mean the unification issue you mentioned)
Reproduction steps
Scala version: 2.13.10
Problem