I have the very simple test:
object Test {
sealed trait Op[I,T,O]
final case class Func[I,T,O](t: I => O) extends Op[I,Nothing,O]
final case class All[I,T,O](f: List[Op[I,T,O]]) extends Op[I,T,O]
def f1(i:Int) = i + 1
def f2(i:Int) = i * 2
def ff1 = Func(f1)
def ff2 = Func(f2)
val ll = List(ff1,ff2)
val all = All(ll)
def main(args: Array[String]): Unit = {
println(all)
}
}
When using 2.12.6 I get the following error:
val all = All(ll)
type mismatch;
found : List[Test.Func[Int,Nothing,Int]]
required: List[Test.Op[Int,T,Int]]
With Dotty (using https://scastie.scala-lang.org/) it runs without a hitch.
I have tried:
val ll:List[Op[Int,Nothing,Int]] = List(ff1,ff2)
But still get the same error. And when I use:
al ll:List[Op[Int,_,Int]] = List(ff1,ff2)
I get:
no type parameters for method apply: (f: List[Test.Op[I,T,O]])Test.All[I,T,O] in object All exist so that it can be applied to arguments (List[Test.Op[Int, _, Int]])
--- because ---
argument expression's type is not compatible with formal parameter type;
found : List[Test.Op[Int, _, Int]]
required: List[Test.Op[?I,?T,?O]]
type mismatch;
found : List[Test.Op[Int, _, Int]]
required: List[Test.Op[I,T,O]]
Am I correct in assuming that the type List[Op[Int,Nothing,Int]]
should be the inferred type?
In other words is Dotty correct (can I expect this behavior in the future)?
And last, but not least, I circumvented this by changing the definition to:
final case class All[I,T,O](f: List[Op[I,_,O]]) extends Op[I,T,O]
Is this Ok, or should I do something else (safer)?
TIA