Is there a better way to define a Type that encapsulates a Union?

66 Views Asked by At

I want to encapsulate a Union of several Types in its own named Type, so that I can use that Type in method signatues, so that I can't forget any of the individual cases and everywhere that Type is used will automatically be updated if I add a new case to the Union.

The only way I've found to do this so far is this, which feels a bit janky:

case class A(x: String)
case class B(y: Int)

case class UnionType(arg: A|B)

def doSomething(du: UnionType) : String =
  du.arg match
    case A(x) => "A"
    case B(y) => "B"

Is there a better way?

1

There are 1 best solutions below

1
Guy On

This looks very clean to me, the only issue is that by default the compiler does not enforce that "new" cases in your union type be matched. But the compiler does warn you about it, so if you want you can make it fail compilation in case of warnings.

To do it

add this flag to your compile command

-Xfatal-warnings

or if you use sbt

scalacOptions ++= Seq("-Xfatal-warnings")

see here

But notice it might fail on other warnings that you may wish to ignore, in that case just suppress them using @nowarn annotation.