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
- type C7 = Sum (Finite 7)
- 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
In this case we used DerivingVia
to derive the action of C7
through the Finitary
instance of NoteName
by using the Finitely
newtype.
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 invert :: Alteration -> Alteration # pow :: Integral x => Alteration -> x -> 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
> invert ( 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 #