Enforcing type equality bound on implicit type parameter

These are some nice refinements over your previous thread; you’re definitely moving in the right direction.

My guess is that you’re trying to avoid the case class layer I suggested in your previous thread. This is pretty close, but as @Jasper-M says, concrete type members like PhantomFunk don’t hold onto phantom parameters that way. More formally, given any types T, U <: AlgorithmType, PhantomFunk[T] = PhantomFunk[U], because

1. PhantomFunk[T] = Double => Either[ADWError, Double] // type alias
2. PhantomFunk[U] = Double => Either[ADWError, Double] // type alias
3. Double => Either[ADWError, Double] = PhantomFunk[U] // equivalence relation symmetry
4. PhantomFunk[T] = PhantomFunk[U] // 2+3 transitivity (from equivalence relation)

And you can get the compiler to prove this, too, implicitly[PhantomFunk[T] =:= PhantomFunk[U]], and it compiles.

So if you want a phantom parameter on a type alias, you have to hide the fact that they’re equal from the compiler. You can use @julianmichael’s approach to newtypes for this.

sealed abstract class PhantomFunkModule {
  type PhantomFunk[T <: AlgorithmType]
  // add more member declarations here for conversion
}

object PhantomFunkModule {
  val Module: PhantomFunkModule = new PhantomFunkModule {
    type PhantomFunk[T <: AlgorithmType] = Double => Either[ADWError, Double]
    // add the member definitions here; they should be trivial
  }
}

Now the compiler knows about the type alias equality only inside the new PhantomFunkModule body; you can prove this with implicitly as above: the implicitly will compile inside that body, but fail outside it. So that way the phantom is preserved, because the compiler can’t just throw it away anymore; it has existential type, and is no longer a type alias.

You might be interested in developments to make this more convenient, like the pre-SIP or @alexknvl’s newts.

If you don’t want to do this, @yawaramin’s example is perfectly fine too; you can even add case to class without causing trouble.

2 Likes