{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.GIS where
import Data.Act (Torsor ((<--)))
import Data.Finitary (Cardinality, Finitary (fromFinite, toFinite))
import Data.Group (Group ((~~)))
import Data.Kind (Type)
import Data.Monoid (Sum (..))
import Data.Pitch (Pitch (..), labelPitch)
class (Group (Interval space)) => GIS space where
type Interval space :: Type
type Interval space = IntervalOf space
ref :: space
int :: space -> space -> Interval space
label :: space -> Interval space
default ref :: (Bounded space) => space
ref = space
forall a. Bounded a => a
minBound
default int :: space -> space -> Interval space
int space
s space
t = space -> Interval space
forall space. GIS space => space -> Interval space
label space
t IntervalOf space -> IntervalOf space -> IntervalOf space
forall m. Group m => m -> m -> m
~~ space -> Interval space
forall space. GIS space => space -> Interval space
label space
s
default label :: (Eq space) => space -> Interval space
label = space -> space -> Interval space
forall space. GIS space => space -> space -> Interval space
int space
forall space. GIS space => space
ref
{-# MINIMAL label | int #-}
type family IntervalOf (space :: Type) :: Type
type PitchClassSpace space =
( Bounded space,
Finitary space,
Finitary (IntervalOf space),
Cardinality space ~ Cardinality (IntervalOf space),
Group (IntervalOf space),
Torsor (IntervalOf space) space
)
instance {-# OVERLAPPABLE #-} (PitchClassSpace space) => GIS space where
int :: space -> space -> Interval space
int space
s space
t = space
t space -> space -> IntervalOf space
forall g x. Torsor g x => x -> x -> g
<-- space
s
label :: space -> Interval space
label = Finite Integer (Cardinality space) -> IntervalOf space
Finite (Cardinality (IntervalOf space)) -> IntervalOf space
forall a. Finitary a => Finite (Cardinality a) -> a
fromFinite (Finite Integer (Cardinality space) -> IntervalOf space)
-> (space -> Finite Integer (Cardinality space))
-> space
-> IntervalOf space
forall b c a. (b -> c) -> (a -> b) -> a -> c
. space -> Finite Integer (Cardinality space)
forall a. Finitary a => a -> Finite (Cardinality a)
toFinite
type PitchSpace space =
( Bounded space,
Finitary space,
IntervalOf (Pitch space) ~ Sum Int
)
instance {-# OVERLAPPABLE #-} (PitchSpace space) => GIS (Pitch space) where
label :: Pitch space -> Interval (Pitch space)
label = Pitch space -> Sum Int
Pitch space -> Interval (Pitch space)
forall a. Finitary a => Pitch a -> Sum Int
labelPitch