content: 
  ----------------------------------------------------------------------------
  -- |
  -- Module      :  Mezzo.Model.Harmony.Motion
  -- Description :  Models of harmonic motion
  -- Copyright   :  (c) Dima Szamozvancev
  -- License     :  MIT
  --
  -- Maintainer  :  ds709@cam.ac.uk
  -- Stability   :  experimental
  -- Portability :  portable
  --
  -- Classes modelling consonance, dissonance and harmonic motion.
  --
  -----------------------------------------------------------------------------
  
  module Mezzo.Model.Harmony.Motion
      (
      -- * Consonant and dissonant intervals
        PerfConsonantInterval
      , ImperfConsonantInterval
      , DissonantInterval
      -- * Harmonic motion
      , DirectMotion
      , ContraryMotion
      , ObliqueMotion
      ) where
  
  import GHC.TypeLits
  
  import Mezzo.Model.Types
  import Mezzo.Model.Prim
  import Mezzo.Model.Errors
  
  -------------------------------------------------------------------------------
  -- Consonant and dissonant intervals
  -------------------------------------------------------------------------------
  
  -- | Classifies perfect consonant intervals:
  --
  --  * Perfect unisons
  --  * Perfect fifths
  --  * Perfect octaves
  class PerfConsonantInterval (i :: IntervalType)
  instance PerfConsonantInterval (Interval Perf Unison)
  instance PerfConsonantInterval (Interval Perf Fifth)
  instance PerfConsonantInterval (Interval Perf Octave)
  
  -- | Classifies imperfect consonant intervals:
  --
  --  * Major and minor thirds
  --  * Major and minor sixths
  class ImperfConsonantInterval (i :: IntervalType)
  instance ImperfConsonantInterval (Interval Maj Third)
  instance ImperfConsonantInterval (Interval Min Third)
  instance ImperfConsonantInterval (Interval Maj Sixth)
  instance ImperfConsonantInterval (Interval Min Sixth)
  
  -- | Classifies dissonant intervals:
  --
  --  * Perfect fourth (by common practice convention)
  --  * Augmented and diminished intervals
  --  * Second and seventh intervals
  class DissonantInterval (i :: IntervalType)
  instance DissonantInterval (Interval Perf Fourth)
  instance DissonantInterval (Interval Aug is)
  instance DissonantInterval (Interval Dim is)
  instance DissonantInterval (Interval ic Second)
  instance DissonantInterval (Interval ic Seventh)
  
  -------------------------------------------------------------------------------
  -- Harmonic motion
  -------------------------------------------------------------------------------
  
  -- | Ensures that direct motion is permitted between the two intervals.
  class DirectMotion (e :: DyadPair) (i1 :: IntervalType) (i2 :: IntervalType)
  instance {-# OVERLAPPING #-} MotionError "Parallel unisons are forbidden: " e
                                  => DirectMotion e (Interval Perf Unison) (Interval Perf Unison)
  instance {-# OVERLAPS #-} MotionError "Direct motion into a perfect unison is forbidden: " e
                                  => DirectMotion e i1 (Interval Perf Unison)
  instance {-# OVERLAPPING #-} MotionError "Parallel fifths are forbidden: " e
                                  => DirectMotion e (Interval Perf Fifth) (Interval Perf Fifth)
  instance {-# OVERLAPS #-} MotionError "Direct motion into a perfect fifth is forbidden: " e
                                  => DirectMotion e i1 (Interval Perf Fifth)
  instance {-# OVERLAPPING #-} MotionError "Parallel octaves are forbidden: " e
                                  => DirectMotion e (Interval Perf Octave) (Interval Perf Octave)
  instance {-# OVERLAPS #-} MotionError "Direct motion into a perfect octave is forbidden: " e
                                  => DirectMotion e i1 (Interval Perf Octave)
  instance {-# OVERLAPPABLE #-}      DirectMotion e i1 i2
  
  -- | Ensures that contrary motion is permitted between the two intervals.
  class ContraryMotion (i1 :: IntervalType) (i2 :: IntervalType)
  instance ContraryMotion i1 i2
  
  -- | Ensures that oblique motion is permitted between the two intervals.
  class ObliqueMotion (i1 :: IntervalType) (i2 :: IntervalType)
  instance ObliqueMotion i1 i2
  