Proposal for Opaque Type Aliases

I’m not sure the implied constructor is a problem:

val mag: Mag = "hey"
// but that is also ok:
val mag: Mag = Mag("hey")
// or
val mag = Mag("hey")

I do however think that the = is irregular and confusing in this location, as it doesn’t exist for other “entities”.

And there’s still the problem of the square brackets, which imply that the opaque should be declared Mag[_], but in fact it’s Mag.

Maybe something like this?

opaque Mag(s: Mag.S) { ... }
object Mag {
  type S <: String
}

Though I don’t like abstract type syntax inside objects in the first place (discussed earlier).

Maybe use trait inheritance?

trait MagT {
  type S <: String
}
opqaue Mag(s: Mag.S) extends MagT {
  type S = String
}
// or
trait MagT[S <: String] {
  def s: S
}
opqaue Mag(s: String) extends MagT[String] {

Though both of these look bizzare.

I am not sure what newtype is, and I haven’t thought about nominal types and their interaction with implicit lookup; again, I believe their semantics need to be further explored.