Adjective
Adjective copied to clipboard
Work around the runtime type issues in Scala.
From the running spec:
// First, we define the precise types that make up our domain/universe/ontology
object PersonOntology {
// `Adjective[T]` is the building block of our type algebra
// Try to make them as atomic as possible
case object DbId extends Adjective[Int] ((id)=> 0 <= id && id < 2000000)
case object NameSequence extends Adjective[String] (_.matches("^[A-Z][a-zA-Z]{1,31}$"))
case object DisallowedSequences extends Adjective[String] (_.toLowerCase.contains("fbomb"))
case object ScottishLastName extends Adjective[String] (_ startsWith "Mc")
case object JewishLastName extends Adjective[String] (_ endsWith "berg")
// We use boolean algebra to combine base adjectives into more nuanced adjectives
val LegalName = NameSequence & ~DisallowedSequences // `~X` negates `X`
val FirstName = LegalName
val SomeHeritageLastName = LegalName & (ScottishLastName <+> JewishLastName) // `<+>` stands for Xor, ⊕ is the math notation
}
// < ... Irrelevant things go here >
// Trying to precisely type the Includes/Excludes exposes a
// little bit of clunkiness in the path-dependent types of `val`s
validPerson shouldBe Right(
Person(
Includes(DbId,123), // this works great because DbId is a type, not a `val`
Includes(FirstName, "Bilbo").asInstanceOf[FirstName.^], // ouch!
Includes(SomeHeritageLastName, "McBeggins").asInstanceOf[SomeHeritageLastName.^])) // one more ouch.
This is very clunky, and detracts from both the usability and safety of using the library.
I believe it is caused by the fact that Scala treats static and dynamic type declarations differently, with the dynamically-declared type being a second-rate citizen.
We should create a mechanism whereby this wart is either hidden behind some library interface, or avoided altogether.