{-# Language TypeFamilies #-}
module Temporal.Class(
DurOf, Duration(..), Compose(..), loopBy, melMap, harMap,
Delay(..), (+|),
Rest(..), Stretch(..), (*|), Limit(..),
Loop(..)
) where
-- | Calculates duration.
class Duration a where
dur :: a -> DurOf a
-- | Duration for the given type.
type family DurOf a :: *
class Compose a where
-- | Sequent composition for a list of values (melody).
mel :: [a] -> a
-- | Parallel composition for a list of values (harmony).
har :: [a] -> a
-- | Sequent composition. Play first track then second.
(+:+) :: a -> a -> a
-- | Parallel composition. Play two tracks simultaneously.
(=:=) :: a -> a -> a
a =:= b = har [a, b]
a +:+ b = mel [a, b]
har = foldl1 (=:=)
mel = foldl1 (+:+)
-- | Repeats the given audio segment several times.
loopBy :: Compose a => Int -> a -> a
loopBy n = mel . replicate n
class Delay a where
-- | Delays the sound source by the given duration.
del :: DurOf a -> a -> a
class Stretch a where
-- | Delays the sound source by the given duration factor.
str :: DurOf a -> a -> a
-- | Infix 'del' function.
(+|) :: Delay a => DurOf a -> a -> a
(+|) = del
-- | Infix 'str' function.
(*|) :: Stretch a => DurOf a -> a -> a
(*|) = str
class Compose a => Rest a where
rest :: DurOf a -> a
class Limit a where
-- | Limits the duration of the sound source.
lim :: DurOf a -> a -> a
class Loop a where
-- | Loops over the sound
loop :: a -> a
-- | Transforms a sequence and then applies a mel.
melMap :: (Compose b) => (a -> b) -> [a] -> b
melMap f xs = mel $ fmap f xs
-- | Transforms a sequence and then applies a har.
harMap :: (Compose b) => (a -> b) -> [a] -> b
harMap f xs = har $ fmap f xs