I am trying to create an implementation of a trait that uses a match type, where the right-hand-side of that match type is known in advance. However, I can't seem to get the compiler to accept my "proof" of this. This is pretty new to me, so sorry if this is really obvious. Can someone help me understand if/how I can achieve what I want?
Here's some minimal code (Scastie) to illustrate what I'm doing:
class NumberBox {} class LongBox {} trait Boxer[T] { def box(): Boxer.Box[T] } object Boxer { type Box[T] = T match case Long => LongBox case _ => NumberBox } case class Val[T](v: T) extends Boxer[T] { def box(): Boxer.Box[T] = v match case _: Long => new LongBox() case _ => new NumberBox() } // here we prove that Boxer.Box[T] is a NumberBox case class NoLongs[T](v: Boxer[T])(using Boxer.Box[T] =:= NumberBox) extends Boxer[T] { override def box(): Boxer.Box[T] = new NumberBox() } NoLongs(Val(1)) But this fails with:
Found: NumberBox Required: Boxer.Box[T] Note: a match type could not be fully reduced: trying to reduce Boxer.Box[T] failed since selector T does not match case Long => LongBox and cannot be shown to be disjoint from it either. Therefore, reduction cannot advance to the remaining case case _ => NumberBox override def box(): Boxer.Box[T] = new NumberBox()