I am very much behind opaque types, and I don’t actually think they add too much verbosity in most situations. However, for basic wrappers, they do.
Let me motivate my concern with the following example:
case class BrittleUser(id: Long, firstName: String, lastName: String, email: String)
case class User(id: User.Id, firstName: User.FirstName, lastName: User.LastName, email: User.Email)
object User {
case class Id(value: Long) extends AnyVal
case class FirstName(value: String) extends AnyVal
case class LastName(value: String) extends AnyVal
case class Email(value: String) extends AnyVal
}
By using a few short wrapper types, you get type safety, preventing you from getting the order of the fields wrong. However, to accomplish the same with opaque types is… a little bit ridiculous.
I like the idea of opaque types, and I think they add flexibility at extremely low cost for types which are more than a simple wrapper (such as your Mode
type). However, in some situations, they lose to AnyVal
s in source maintainability even though they win in performance.