Algebraic Data Type (ADT)
Define Data in Companion Object
When defining an ADT, define the data in the companion object.
So instead of writing ADT like this,
With this, naming conflict in data can be avoided and the companion object can be a namespace so that it is easy to access all the available data constructors in each ADT.
MissingField belongs to
ValidationError, it can be used as
ValidationError.MissingField so no need to repeat
Error in its data name like
It's the same in
Use Constructor Methods
To save time to create all constructor methods, use IDE's auto-complete templates. For IntelliJ IDEA, try this one at this blog post. The link to download can be found at https://blog.kevinlee.io/2019/10/01/save-your-time-on-algebraic-data-type-creation-in-scala/#get-the-template-settings (The demo video of the template).
There can be unwanted types created if data constructors are used. This is an issue with Scala as there is no better way to keep the data hidden and not expose as a type.
As you can see, you've got
List[MyNumber.SomeNumber] instead of
If you mix more than one data class, you get some weirdly inferred type like this.
As you can see, it's not
Product with MyNumber with Serializable.
This is because Scala compiler infers the common type of
case class is a
Product and also
these are the common types of the both case classes along with
To avoid all these issues, you can use the constructor methods like this.
Now the type is
List[MyNumber] as you wanted.
Either use data constructors provided by FP libraries like Scalaz and Cats.