C'è qualche possibilità di scrivere "C major" invece di "major C"?
Ho incontrato un piccolo problema estetico nel mio progetto musicale e mi ha dato fastidio per qualche tempo.
Ho un tipo data Key = C | D | ...
e posso costruire una Scale
da una Key
e un Mode
. Il Mode
distingue tra, per esempio, una scala maggiore e una minore.
Posso definire il tipo Mode
come una funzione da Key
a Scale
. In questo caso i modi avranno nomi minuscoli (il che va bene) e posso ottenere una scala come questa
aScale = major C
Ma i musicisti non parlano così. Si riferiscono a questa scala come la scala C major, non la scala major C.
Cosa voglio
Idealmente vorrei scrivere
aScale = C major
È possibile?
Cosa ho provato
Posso fare di Key
una funzione che costruisce una Scala
da un Mode
, quindi posso scrivere
aScale = c Major
Ma non posso limitare le chiavi alla costruzione di scale. Sono necessarie anche per altre cose (per esempio costruire accordi). Anche Key
dovrebbe essere un'istanza di Show
.
Posso mettere il Mode
dopo il Key
quando uso una funzione extra (o un costruttore di valori):
aScale = scala C major
con scale :: Key -> Mode -> Scale
.
Ma la parola extra scala sembra rumorosa e, contrariamente al suo nome, scale
non si occupa veramente di scale. La parte intelligente è in major
, scale
è davvero solo flip ($)
.
Usare un newtype Mode = Major | Minor ...
non cambia molto, tranne che scala
deve essere più intelligente:
aScale = scale C Major
Soluzione 1:
Usare questo
Ora puoi scrivere (con la C maiuscola e la M maiuscola)
Soluzione 2a:
Anche questo è possibile
Ora si scrive
Soluzione 2b:
Anche questo è possibile
Ora si scrive
Ecco una soluzione stravagante che non consiglio, ma che sembra molto "musicale":
Poi si può scrivere
Naturalmente, dove questo è veramente mirato è che si avrebbe anche
F♯ minore
eB♭ maggiore
ecc.Se non ti dispiace un operatore extra, potresti usare
&
daData.Function
. Assumendo chemajor
sia una funzioneKey -> Scale
, potresti scrivereC & major
. Questo produce un valoreScale
:Ci sono già diverse buone risposte, ma ecco una soluzione di stile che può essere utile (forse non per questo particolare esempio, ma in altri contesti in cui si vuole una sorta di sintassi di applicazione inversa).
Con definizioni standard per alcuni tipi di dominio problematici:
è possibile introdurre un tipo di passaggio continuo:
e scrivere i primitivi tipi di costruzione di note per costruire i tipi di "Contenuti" in questo modo:
Quindi, le funzioni di costruzione di scale, note e accordi possono risolvere i
Cont's a tipi semplici in entrambe le forme postfix (cioè, come continuazioni da passare al
Cont's):o forma di prefisso (cioè, prendendo come argomenti `Cont's):
Ora, puoi scrivere:
Si noti che
c
in sé non ha un'istanza diShow
, mac note
lo fa.Con una modifica al tipo
Note
, si potrebbero facilmente supportare doppi incidenti (ad esempio,c sharp sharp
, distinta dad
), ecc.Si possono usare le classi tipografiche per aggirare abilmente questo problema:
Ora, è possibile utilizzare le lettere minuscole anche per altri tipi definendo le istanze appropriate.