module Music.Time.Delayable (
Delayable(..),
undelay,
delaying,
move,
moveBack,
delayTime,
NoDelay(..),
) where
import Data.AffineSpace
import Data.AffineSpace.Point
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Semigroup
import Data.Set (Set)
import qualified Data.Set as Set
import Data.VectorSpace hiding (Sum)
import Music.Time.Time
class Delayable a where
delay :: Duration -> a -> a
delay _ = id
instance Delayable Time where
delay n = (.+^ n)
instance Delayable (Time -> a) where
delay n = (. delay (negateV n))
instance Delayable a => Delayable [a] where
delay n = fmap (delay n)
instance (Ord a, Delayable a) => Delayable (Set a) where
delay n = Set.map (delay n)
instance Delayable a => Delayable (Map k a) where
delay n = fmap (delay n)
instance Delayable (Time, a) where
delay n (t, a) = (n `delay` t, a)
instance Delayable (Time, Duration, a) where
delay n (t, d, a) = (n `delay` t, d, a)
instance Delayable a => Delayable (Sum a) where
delay n (Sum x) = Sum (delay n x)
instance Delayable a => Delayable (Product a) where
delay n (Product x) = Product (delay n x)
move :: Delayable a => Duration -> a -> a
moveBack :: Delayable a => Duration -> a -> a
delayTime :: Delayable a => Time -> a -> a
undelay t = delay (negateV t)
move = delay
moveBack t = delay (negateV t)
delayTime t = delay (t .-. origin)
delaying :: (Delayable a, Delayable b) => Duration -> (a -> b) -> a -> b
delaying t f = undelay t . f . delay t
newtype NoDelay a = NoDelay { getNoDelay :: a }
deriving (Eq, Ord, Enum, Show, Semigroup, Monoid
)
instance Delayable (NoDelay a) where
delay _ = id