Can an opaque type somehow implement an existing interface?

I can define a type that represents a small set as a bit field:

opaque type SmallIntSet = Int

and implement the usual set methods as extensions. Is there any way to make SmallIntSet a subtype of Set[Int]?

1 Like
scala> opaque type T <: Set[Int] = collection.immutable.HashSet[Int]

You need 3.6 REPL for opaque.

Maybe I’m not the only one who reads 3.nightly as “Knightly”.

No, because it’s not a scala.collection.immutable.Set[Int]. It’s actually just an Int (with custom extensions).

If you have a typeclass that abstracts Set[Int] operations, then SmallIntSet could have an instance of that typeclass. But you can’t force something into the supertype hierarchy that isn’t there. To get in, you have to inherit.

I misunderstood the question if it wasn’t about syntax.

I would have been mildly but pleasantly surprised if this worked:

class BS(val i: Int) extends AnyVal:
  def ++(j: Int) = i + j + j

object X:
  opaque type B <: BS = Int
  def b(i: Int): B = i

object Y:
  import X.*

  def f = X.b(42) ++ 5

@main def test() = println:
  Y.f

It doesn’t allow the type def:

  |object X cannot be instantiated since it has a member B with possibly conflicting bounds Int <: ... <: BS & Int
1 error found

Of course the language doesn’t promote to the boxed form; it unboxes AnyVals at erasure if it can.

1 Like

That’s what I expected. I just wanted to make sure there isn’t any Scala dark magic I’m not aware of that’d get around the problem.