У меня была идея реализовать свой собственный маленький модуль теории музыки в Haskell.
Начиная с примечаний (Note
) имеет смысл, и тут же я столкнулся с этой неприятной синтаксической проблемой, я понятия не имею, как с ней справляются настоящие Хаскелеры.
data Note = Sharp NoteS | Flat NoteF deriving (Show)
data NoteS =
C | SC | D | SD | E | F | SF | G | SG | B
deriving (Ord,Show,Eq)
data NoteF =
C | FD | D | FE | E | F | FG | G | FB | B
deriving (Ord,Show,Eq)
instance Eq Note where
(==) (NoteS n1) (NoteS n2) = n1 == n2
(==) (NoteF n1) (NoteF n2) = n1 == n2
(==) (NoteS n1) (NoteF n2) = ???
(==) (NoteF n1) (NoteS n2) = ???
...
flatToSharp :: Note -> NoteS
sharpToFlat :: Note -> NoteF
Как многие могут знать, острый C и плоский D являются синонимами в целом, но иногда предпочитают использовать один или другой в зависимости от контекста. Поэтому я надеялся использовать тот факт, что и NoteS
, и NoteF
являются экземплярами Ord
(например, для вычисления интервала). Но в обоих представлениях простые заметки (C, D, E, F ...) имеют одинаковые имена в обоих типах.
Теперь я мог бы придумать, как "взломать" эту синтаксическую проблему. Но это может иметь либо отвратительные синтаксические последствия, либо последствия времени выполнения (например, использовать Strings вместо типов, много тестирования и проверки ошибок, ...).
Итак, вот мой вопрос к профессионалам Haskell ... Как бы я сделал это в духе моей идеи, не слишком много уступок этой проблеме "пространства имен" Haskell?
Я пытался {-# LANGUAGE DuplicateRecordFields #-}
, но это не помогает с профсоюзами, очевидно.