haskell - 如何定义所有音符名称.. Cbb Cb C Cs Css .. 作为 Haskell 中的构造函数
问题描述
我正在演奏音符名称,其目标是不混淆等音等号,即我想让临时记号(升号和降号)正确。音符上方完美五度的音符B
必须是Fs
和 不是Gb
,即使Fs
和Gb
是钢琴键盘上的同一个键。
此外,我希望Fs
在 haskell 程序中方便地编写 ee,无需空格、引号或额外的函数。
我最终定义了 35 个构造函数,范围Cbb
从Bss
. 虽然这很有效,并且确实使临时记号正确,但我对最多两个临时记号的限制感到不满。Int
在内部,无论如何我们表示为s 的变音记号。
- 有没有办法像标题中所指出的那样定义无限数量的构造函数,所以
Cbbbb
可以使用带有任意数量的临时记号(如 )的音符?模板haskell可能吗? - 或者,我是否可以在不创建构造函数的情况下方便地编写
Cbbbb
haskell 程序(不带引号、空格或额外函数)Cbbbb
?
解决方案
我同意 Carsten 的观点,实际上有很多这样的分散构造函数是个坏主意。使用像这样的数据更明智
data BaseNote = C | D | E | F | G | A | B
data PitchClass = PitchClass
{ baseNote :: BaseNote
, accidentals :: Int }
data Note = Note
{ pitchClass :: PitchClass
, octave :: Int }
至于
此外,我希望
Fs
在 haskell 程序中方便地编写 ee,无需空格、引号或额外的函数。
你有多种选择。
你可以使用
-XPatternSynonyms
. 这使您可以为已定义的数据类型获取可匹配的构造函数。{-# LANGUAGE PatternSynonyms #-} pattern Cn = PitchClass C 0 pattern Cs = PitchClass C 1 pattern Cb = PitchClass C (-1) ...
这些可以由 TemplateHaskell 宏提供以避免代码重复。
您可以提供一个函数,使其看起来像单个构造函数名称一样紧凑,但实际上并非如此。
(♮), (♯), (♭) :: BaseNote -> Int -> Note bn♮octv = Note (PitchClass bn 0) octv bn♯octv = Note (PitchClass bn 1) octv bn♭octv = Note (PitchClass bn (-1)) octv
现在你可以写像
[A♮2, A♮2, C♯3, C♯3, D♮3, D♮3, C♯3]
TBH 我不认为这两个真的很好。IMO 更有意义的是,根本不以绝对音高来指定音乐素材,而是以音阶或音程步长的序列来指定音乐素材。
推荐阅读
- javascript - 如何在nodejs中访问函数和类之外的变量值
- ruby-on-rails - 在 Rails 中增加 IMAP 块大小
- php - 为什么 \p{Ll} 不匹配小写变音符号?
- google-app-maker - 使用 Google AppMaker 进行布尔搜索
- c# - 如何在 ashx 中返回数据类型 JSON
- mysql - 如何从连接表中选择最大表?
- javascript - 两个包含图像的滚动同步 div - 如何防止事件适得其反?
- python - Bayer Demosaicing VideoCaptured python中的帧
- amazon-web-services - 在 Amazon SNS 控制面板中创建平台应用程序的选项在哪里?
- python - Python:使用 subprocess.Popen 执行一个长时间运行的进程,将其杀死并访问其输出