W moim projekcie muzycznym napotkałem niewielki problem estetyczny i od pewnego czasu mnie to denerwuje.
Mam typ data Key = C | D | ...
i mogę zbudować Scale
a Key
i a Mode
. W Mode
rozróżnia np główną i mniejszą skalę.
Mogę zdefiniować Mode
typ jako funkcję od Key
do Scale
. W takim przypadku tryby będą miały małe litery (co jest w porządku) i mogę uzyskać taką skalę
aScale = major C
Ale muzycy tak nie mówią. Odnoszą się do tej skali jako do skali C-dur , a nie do skali C-dur .
Czego chcę
Idealnie chciałbym pisać
aScale = C major
Czy to w ogóle jest możliwe?
Co próbowałem
Mogę stworzyć Key
funkcję, która konstruuje Scale
z a Mode
, więc mogę pisać
aScale = c Major
Ale nie mogę ograniczyć kluczy do budowania Łusków. Są one również potrzebne do innych rzeczy (np. Do tworzenia akordów ). Key
Powinien też być przypadek Show
.
Mogę umieścić Mode
po, Key
kiedy używam dodatkowej funkcji (lub konstruktora wartości):
aScale = scale C major
z scale :: Key -> Mode -> Scale
Ale dodatkowa skala słów wygląda głośno i wbrew nazwie, scale
tak naprawdę nie dotyczy skal. Inteligentna część jest w środku major
, scale
jest naprawdę sprawiedliwa flip ($)
.
Używanie newtype Mode = Major | Minor ...
naprawdę niewiele się zmienia, poza tym scale
musi być bardziej inteligentny:
aScale = scale C Major
major C
.