J'ai rencontré un petit problème esthétique dans mon projet musical et cela me dérange depuis un certain temps.
J'ai un type data Key = C | D | ...
et je peux construire un à Scale
partir d'un Key
et d'un Mode
. Le fait la Mode
distinction entre, par exemple, une échelle majeure et une échelle mineure.
Je peux définir le Mode
type en fonction de Key
à Scale
. Dans ce cas, les modes auront des noms en minuscules (ce qui est bien) et je peux obtenir une échelle comme celle-ci
aScale = major C
Mais les musiciens ne parlent pas comme ça. Ils se réfèrent à cette échelle comme l' échelle majeure en C , et non pas l' échelle majeure en C.
Ce que je veux
Idéalement, je voudrais écrire
aScale = C major
Est-ce possible?
Ce que j'ai essayé
Je peux faire Key
une fonction qui construit un à Scale
partir d'un Mode
, donc je peux écrire
aScale = c Major
Mais je ne peux pas limiter les clés à la construction des échelles. Ils sont également nécessaires pour d'autres choses (par exemple la construction d' accords ). Devrait également Key
être une instance de Show
.
Je peux mettre l' Mode
after Key
quand j'utilise une fonction supplémentaire (ou constructeur de valeur):
aScale = scale C major
avec scale :: Key -> Mode -> Scale
Mais l' échelle de mot supplémentaire semble bruyante et contrairement à son nom, elle scale
ne s'intéresse pas vraiment aux échelles. La partie intelligente est dedans major
, scale
c'est vraiment juste flip ($)
.
Utiliser un newtype Mode = Major | Minor ...
ne change pas vraiment grand chose, sauf qu'il scale
doit être plus intelligent:
aScale = scale C Major
major C
.Réponses:
Solution 1:
Utilisez ceci
Vous pouvez maintenant écrire (avec les majuscules C et les majuscules M)
Solution 2a:
C'est aussi possible
Maintenant tu écris
Solution 2b:
C'est aussi possible
Maintenant tu écris
la source
Voici une solution fantaisiste que je ne recommande pas vraiment, mais qui semble très «musicale»:
Ensuite, vous pouvez écrire
Bien sûr, où cela vise vraiment, c'est que vous auriez aussi
F♯ minor
etB♭ major
etc.la source
⠀
U + 2800 BRAILLE PATTERN BLANK peut être utilisé comme infixe. Inutile de dire que c'est une idée horrible ... Tous les personnages spatiaux réels sont interdits en tant qu'infixes, mais sans surprise Unicode contient quelque chose qui peut être piraté dans le but d'abus.Si cela ne vous dérange pas un opérateur supplémentaire, vous pouvez utiliser à
&
partir deData.Function
. En supposant quemajor
c'est une fonctionKey -> Scale
, vous pourriez écrireC & major
. Cela produit uneScale
valeur:la source
Il existe déjà plusieurs bonnes réponses, mais voici une solution de style de passage de continuation qui peut être utile (peut-être pas pour cet exemple particulier, mais dans d'autres contextes où une sorte de syntaxe d'application inverse est souhaitée).
Avec des définitions standard pour certains types de domaines problématiques:
vous pouvez introduire un type passant-continuation:
et écrivez les types primitifs de création de notes pour créer des
Cont
types comme ceci:Ensuite, les fonctions de construction d'échelle, de note et d'accords peuvent résoudre les
Cont
s en types simples sous l'une ou l'autre forme de suffixe (c'est-à-dire en tant que continuations à transmettre à laCont
):ou sous forme de préfixe (c'est-à-dire en prenant
Cont
s comme arguments):Maintenant, vous pouvez écrire:
Notez que
c
lui - même n'a pas d'Show
instance, mais en ac note
.Avec une modification du
Note
type, vous pourriez facilement prendre en charge les doubles accidents (par exemplec sharp sharp
, distincts ded
), etc.la source
Cont
cependant, j'ai essayé de le coller aux constructeursA | B | C ...
au lieu d'utiliser des fonctions. Je n'ai pas pu faire fonctionner cela et je ne comprends toujours pas pourquoi, étant donné que les constructeurs de valeur ne sont que des fonctions. Si je peux coller une fonction devant mes touches, beaucoup de choses deviennent possibles. Si la fonction estflip ($)
alors j'obtiens votre modèleflip ($) B :: Cont Key r
. Mon originalaScale = scale C Major
n'est pas très différent.Vous pouvez utiliser des classes de types pour contourner intelligemment ce problème:
Maintenant, vous pouvez également utiliser les lettres minuscules pour d'autres types en définissant des instances appropriées.
la source