module Synthesizer.Dimensional.Amplitude where

import qualified Number.DimensionTerm        as DN
-- import qualified Algebra.DimensionTerm       as Dim

{- |
Can be used as amplitude value for enumeration types
such as 'Bool' and 'Ordering'
and other types, where a numeric amplitude makes no sense.
It is essential in 'Synthesizer.Dimensional.Causal.Process.T'.
It would be a bad idea to omit the @Abstract@ parameter
in dimensional causal processes
since the correspondence between amplitude type and sample type would be lost.
data Abstract = Abstract

newtype Numeric amp = Numeric amp

instance Functor Numeric where
   fmap f (Numeric amp) = Numeric $ f amp

type Dimensional v y = Numeric (DN.T v y)

{- |
@Flat y@ is quite the same as @Dimensional Dim.Scalar y@
but in some cases it allows a little more efficient processing.
It should not be mixed up with @Abstract@.
@Flat y@ is reserved for numeric amplitudes.
data Flat y = Flat

{- |
This class is used to make 'Synthesizer.Dimensional.Causal.Process.mapAmplitude'
both flexible and a bit safe.
Its instances are dimensional numbers 'Numeric' and 'Abstract'.
It should not be necessary to add more instances.
class C amp where

instance C Abstract where

instance C (Flat y) where

instance C (Numeric amp) where

-- instance Dim.C v => C (DN.T v y) where

{- |
This class is used for 'Synthesizer.Dimensional.Rate.Cut.append'
and ''
that expect that the amplitude value
does carry not more information than that expressed by the type.
It should not be necessary to add more instances.
class Primitive amp where
   primitive :: amp

instance Primitive Abstract where
   primitive = Abstract

instance Primitive (Flat y) where
   primitive = Flat