Encontré un pequeño problema estético en mi proyecto de música y me ha estado molestando durante algún tiempo.
Tengo un tipo data Key = C | D | ...y puedo construir a Scalede a Keyy a Mode. El Modedistingue entre, por ejemplo, una escala mayor y una menor.
Puedo definir el Modetipo como una función de Keya Scale. En ese caso, los modos tendrán nombres en minúscula (lo cual está bien) y puedo obtener una escala como esta
aScale = major C
Pero los músicos no hablan así. Se refieren a esta escala como la escala C mayor , no la escala C mayor .
Lo que quiero
Idealmente me gustaría escribir
aScale = C major
¿Es esto posible en absoluto?
Lo que probé
Puedo hacer Keyuna función que construya a Scaledesde a Mode, así puedo escribir
aScale = c Major
Pero no puedo limitar Keys a construir escalas. También son necesarios para otras cosas (por ejemplo, construir acordes ). tambiénKey debería ser una instancia de Show.
Puedo poner el Mode después de Keycuando uso una función adicional (o constructor de valores):
aScale = scale C major con scale :: Key -> Mode -> Scale
Pero la escala de palabras adicional parece ruidosa y, al contrario de su nombre, scaleno se preocupa realmente por las escalas. La parte inteligente está adentro major, scalees realmente justa flip ($).
El uso de a newtype Mode = Major | Minor ...no cambia mucho, excepto que scalenecesita ser más inteligente:
aScale = scale C Major
major C.