I have the following:
sealed trait Tag
case object MyTag1 extends Tag
case object MyTag2 extends Tag
sealed trait Error[T <: Tag]
// error implementations...
I'd like for two Error
implementations using the same Tag
to fail at compile time, but not fail in the case there are Tag
s without an associated Error
.
The compilation guard given in the first answer here: How can I verify type existence on compile time in Scala comes very close to what I want, but fails at compile time if there exists a Tag
without an associated Error
.
You can try to add one more case to the Poly
def compilationGuard[C <: Coproduct]()(implicit
gen: Generic.Aux[Signal, C],
mapper: Mapper[uniqueDescriptionPoly.type, C]
) = null
object uniqueDescriptionPoly extends Poly1 {
implicit def cse[S <: Signal, C1 <: Coproduct](implicit
gen1: Generic.Aux[Description[S], C1],
ev: C1 <:< (_ :+: CNil)
): Case.Aux[S, Null] = null
implicit def cse0[S <: Signal, C1 <: Coproduct](implicit
gen1: Refute[Generic[Description[S]]]
): Case.Aux[S, Null] = null
}
compilationGuard()
final case class S1(name: String) extends Signal
final case class S2(name: String) extends Signal
final case class D1(name: String) extends Description[S1]
//compiles
final case class S1(name: String) extends Signal
final case class S2(name: String) extends Signal
final case class D1(name: String) extends Description[S1]
final case class D2(name: String) extends Description[S1]
// doesn't compile
final case class S1(name: String) extends Signal
final case class S2(name: String) extends Signal
final case class D1(name: String) extends Description[S1]
final case class D2(name: String) extends Description[S2]
// compiles