Есть ли шанс написать «C major» вместо «major C»?
Я столкнулся с небольшой эстетической проблемой в моем музыкальном проекте, и это беспокоило меня в течение некоторого времени.
У меня есть тип data Key = C | D | ...
и я могу построитьМасштаб
изКлюча
иМод
. «Режим» различает, например,. крупный и второстепенный масштаб.
Я могу определить тип Mode
как функцию от Key
до Scale
. В этом случае режимы будут иметь строчные имена (что хорошо), и я могу получить такую шкалу
aScale = major C
Но музыканты так не говорят. Они называют эту шкалу C major, а не major C.
Что я хочу
В идеале я бы хотел написать
aScale = C major
Возможно ли это вообще?
Что я пробовал
Я могу сделать Key
функцией, которая создает Scale
из Mode
, чтобы я мог писать
aScale = c Major
Но я не могу ограничить Ключи построением Весов. Они нужны и для других вещей (например,. строительство аккордов ). Также «Ключ» должен быть экземпляром «Показать».
Я могу поместить Mode
после Key
, когда использую дополнительную функцию (или конструктор значений):
aScale = масштаб C major
с scale :: Key - > Режим - > Масштаб
Но дополнительное слово scale выглядит шумно и вопреки своему названию, «scale» на самом деле не касается весов. Интеллектуальная часть в «major», «scale» на самом деле просто «flip ($)».
Использование newtype Mode = Major | Minor ...
на самом деле мало что меняет, кроме scale
должен быть более умным:
aScale = scale C Major
Решение 1:
Используйте это
Теперь вы можете написать (с большой буквы C и заглавной буквы M)
Решение 2а:
Это также возможно
Теперь пиши
Решение 2b:
Это также возможно
Теперь пиши
Вот одно причудливое решение, которое я не очень рекомендую, но выглядит очень «музыкально»:
Тогда ты можешь написать
Конечно, это действительно нацелено на то, что у вас также будут «F♯ minor» и «B ₣ major» и т. Д..
Если вы не возражаете против дополнительного оператора, вы можете использовать
&
изData.Function
. Предполагая, чтоmajor
является функциейKey - > Масштаб
, вы можете написатьC & майор
. Это производит значениеScale
:Уже есть несколько хороших ответов, но вот решение для прохождения стиля продолжения, которое может быть полезным (возможно, не для этого конкретного примера, а в других контекстах, где требуется своего рода синтаксис обратного приложения).
Со стандартными определениями для некоторых типов проблемных доменов:
Вы можете ввести тип прохождения продолжения:
и напишите примитивные типы создания заметок, чтобы создать типы
Cont
, как это:Затем функции построения масштаба, ноты и аккордов могут разрешать
Cont
s для простых типов в любой форме postfix (т.е., как продолжение, которое должно быть передано вCont
):или префиксная форма (т.е., принимая
Cont
s в качестве аргументов):Теперь вы можете написать:
Обратите внимание, что у
c
нет экземпляраShow
, а уc note
есть.С модификацией типа «Примечание» вы можете легко поддерживать двойные случайные (например,.,
c острый острый
, отличается отd
) и т. д.Вы можете использовать классы типов, чтобы ловко обойти это:
Теперь вы можете использовать строчные буквы и для других типов, определяя соответствующие экземпляры.