Yes, we can use the familiar HasX
here
trait HasPitchClasses:
def pitchClasses: Set[PitchClass]
but still kind of artificial from a domain perspective as Chord
and Scale
are different things. Creating these HasX
feels a bit boilerplaty, but the contract + docs-in-one-place-argument is of course strong.
But what about Set[PitchClass]
in the Filter
union? I could of course wrap it in
case class PitchClasses(pitchClasses: Set[PitchClass]) extends HasPitchClasses
but then I get some confusion of when to use Set[PitchClass]
and PitchClasses
from the library user’s point of view, and I wouldn’t want to open Pandoras box of implicit conversion here (see other exciting thread ).
And we have Empty
in the union, which I use in more places than just as “is a HasPitchClass thing” so, I want to avoid using inheritance there.
So all in all I found the
type Filter = Empty | Set[PitchClass] | Scale | Chord
to be so nice and clean