Safe Haskell | None |
---|---|
Language | Haskell2010 |
Illustrative usage of Group
, Act
and Torsor
: manipulation of musical intervals.
The musical distance between two musical notes is a musical interval.
Intervals can be compounded and inverted, so they form a Group
.
Notes can be translated by a given interval, which is an Act
of intervals on notes.
There's a unique musical interval taking any note to any other given one, so notes are a torsor under intervals.
This functionality is useful in providing enharmonically correct voicings of chords.
Synopsis
- data NoteName
- newtype Alteration = Alteration {
- getAlteration :: Int
- data Note = Note {
- name :: NoteName
- alteration :: Alteration
- octave :: Int
- data Interval = Steps {}
- semitones :: Interval -> Int
- straighten :: Interval -> (Sum Int, Sum Int)
- twist :: (Sum Int, Sum Int) -> Interval
- majorTriad :: [Interval]
- diminished7th :: [Interval]
- minor11th :: [Interval]
- mode :: NoteName -> [Interval]
- phrygian :: [Interval]
- lydian :: [Interval]
- wholeTone :: [Interval]
- pattern Natural :: Alteration
- pattern Flat :: Alteration
- pattern DoubleFlat :: Alteration
- pattern Sharp :: Alteration
- pattern DoubleSharp :: Alteration
- pattern Interval :: Int -> Alteration -> Interval
- quality :: Interval -> String
- showOrdinal :: Int -> String
- multiplicity :: Int -> String
Musical notes
We begin by defining note names, which are acted upon by the cyclic group of order 7.
Musical note names.
The enumeration starts with C
to conform with scientific pitch notation.
Instances
Bounded NoteName Source # | |
Enum NoteName Source # | |
Defined in Acts.Examples.MusicalIntervals | |
Eq NoteName Source # | |
Ord NoteName Source # | |
Defined in Acts.Examples.MusicalIntervals | |
Show NoteName Source # | |
Act (C 7) NoteName Source # | |
Torsor (C 7) NoteName Source # | |
In this case we used DerivingVia
to derive the action of C 7
,
using the CyclicEnum
newtype created for this exact purpose.
newtype Alteration Source #
Instances
Show Alteration Source # | |
Defined in Acts.Examples.MusicalIntervals showsPrec :: Int -> Alteration -> ShowS # show :: Alteration -> String # showList :: [Alteration] -> ShowS # | |
Semigroup Alteration Source # | |
Defined in Acts.Examples.MusicalIntervals (<>) :: Alteration -> Alteration -> Alteration # sconcat :: NonEmpty Alteration -> Alteration # stimes :: Integral b => b -> Alteration -> Alteration # | |
Monoid Alteration Source # | |
Defined in Acts.Examples.MusicalIntervals mempty :: Alteration # mappend :: Alteration -> Alteration -> Alteration # mconcat :: [Alteration] -> Alteration # | |
Group Alteration Source # | |
Defined in Acts.Examples.MusicalIntervals inverse :: Alteration -> Alteration # gtimes :: Integral n => n -> Alteration -> Alteration # |
Note the use of DerivingVia
to transfer algebraic operations from Sum Int
.
For non-newtypes, one can use generics, for example:
data Klein4 = Klein4 ( C 2 ) ( C 2 ) deriving stock Generic deriving ( Semigroup, Monoid, Group ) via Generically Klein4
This uses the Generically
newtype from the generic-data
library.
Note names such as A4
or C#6
: note name, alteration, and octave (scientific pitch notation).
Note | |
|
Instances
Show Note Source # | |
Act Interval Note Source # | Intervallically correct action of intervals on notes.
|
Torsor Interval Note Source # | Computes the interval between two notes. > Note C Natural 5 --> Note A Natural 4 minor 3rd down > Note E Flat 4 --> Note A Natural 5 augmented 11th up |
Musical intervals
An interval is represented as a number of scale steps to take (relative to the major scale), together with an additional alteration to apply.
For instance, a major third is two steps up (diatonic steps relative to the root in a major scale):
> Steps ( Sum 2 ) Natural major 3rd up
A minor sixth is 5 steps up, and then a flat:
> Steps ( Sum 5 ) Flat minor 6th up
The smart constructor Interval
is also provided that is more intuitive to use:
> Interval 3 Natural major 3rd up
> Interval 7 Flat minor 7th up
Note that the Semigroup
/Group
operations on intervals are not the obvious ones, e.g.:
> Steps ( Sum 2 ) Natural major 3rd up
> Steps ( Sum (-2) ) Natural minor 3rd down
> inverse ( Steps ( Sum 2 ) Natural ) Steps ( Sum (-2) ) Flat major 3rd down
Musical interval: steps (relative to the root in a major scale) and additional alteration.
Instances
Show Interval Source # | |
Semigroup Interval Source # | |
Monoid Interval Source # | |
Group Interval Source # | |
Act Interval Note Source # | Intervallically correct action of intervals on notes.
|
Torsor Interval Note Source # | Computes the interval between two notes. > Note C Natural 5 --> Note A Natural 4 minor 3rd down > Note E Flat 4 --> Note A Natural 5 augmented 11th up |
semitones :: Interval -> Int Source #
Compute the number of semitones in an interval, using the reference of the C major scale.
To define algebraic operations on intervals,
we use an equivariant bijection to the product group ( Sum Int, Sum Int )
.
Note that ( Sum Int, Sum Int )
is automatically a Semigroup
, Monoid
and Group
using the product structure.
Illustration of the functionality
Chords
majorTriad :: [Interval] Source #
Major triad: major third, perfect fifth.
diminished7th :: [Interval] Source #
Diminished seventh chord: minor third, diminished fifth, diminished seventh.
Example chords:
> majorTriad <&> ( • Note C Natural 4 ) [C4,E4,G4]
> diminished7th <&> ( • Note G Sharp 3 ) [G#3,B3,D4,F4]
> minor11th <&> ( • Note D Natural 3 ) [D3,A3,E4,F4,C5,G5]
Scales
Example scales:
> phrygian <&> ( • Note E Natural 3 ) [E3,F3,G3,A3,B3,C4,D4,E4]
> phrygian <&> ( • Note C Sharp 3 ) [C#3,D3,E3,F#3,G#3,A3,B3,C#4]
> lydian <&> ( • Note C Natural 4 ) [C4,D4,E4,F#4,G4,A4,B4,C5]
> wholeTone <&> ( • Note G Natural 5 ) [G5,A5,B5,C#6,Eb6,F6]
Helper code
End of main example code.
Follows: helper code for reading/showing musical notes and intervals.
pattern Natural :: Alteration Source #
pattern Flat :: Alteration Source #
pattern DoubleFlat :: Alteration Source #
pattern Sharp :: Alteration Source #
pattern DoubleSharp :: Alteration Source #
showOrdinal :: Int -> String Source #
multiplicity :: Int -> String Source #