-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Event lists with relative or absolute time stamps
--   
--   These lists manage events that are associated with times. Times may be
--   given as difference between successive events or as absolute time
--   values. Pauses before the first and after the last event are
--   supported. The underlying data structures are lists of elements of
--   alternating types, that is [b,a,b,...,a,b] or [a,b,a,...,a,b]. The
--   data structures can be used to represent MIDI files, OpenSoundControl
--   message streams, music performances etc.
@package event-list
@version 0.1.0.2


-- | Event lists starting with a body and ending with a body.
module Data.EventList.Relative.BodyBody
data T time body
concatMapMonoid :: Monoid m => (time -> m) -> (body -> m) -> T time body -> m
traverse :: Applicative m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)
mapM :: Monad m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)


-- | Event lists starting with a body and ending with a time difference.
module Data.EventList.Relative.BodyTime
data T time body
empty :: T time body
singleton :: body -> time -> T time body
null :: T time body -> Bool
fromPairList :: [(body, time)] -> T time body
toPairList :: T time body -> [(body, time)]
getTimes :: T time body -> [time]
getBodies :: T time body -> [body]
duration :: Num time => T time body -> time
durationR :: Num time => T time body -> time
mapBody :: (body0 -> body1) -> T time body0 -> T time body1
mapTime :: (time0 -> time1) -> T time0 body -> T time1 body
concatMapMonoid :: Monoid m => (time -> m) -> (body -> m) -> T time body -> m
traverse :: Applicative m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)
traverse_ :: Applicative m => (time -> m ()) -> (body -> m ()) -> T time body -> m ()
traverseBody :: Applicative m => (body0 -> m body1) -> T time body0 -> m (T time body1)
traverseTime :: Applicative m => (time0 -> m time1) -> T time0 body -> m (T time1 body)
mapM :: Monad m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)
mapM_ :: Monad m => (time -> m ()) -> (body -> m ()) -> T time body -> m ()
mapBodyM :: Monad m => (body0 -> m body1) -> T time body0 -> m (T time body1)
mapTimeM :: Monad m => (time0 -> m time1) -> T time0 body -> m (T time1 body)
foldr :: (body -> a -> b) -> (time -> b -> a) -> b -> T time body -> b
foldrPair :: (body -> time -> a -> a) -> a -> T time body -> a
cons :: body -> time -> T time body -> T time body
snoc :: T time body -> body -> time -> T time body
viewL :: T time body -> Maybe ((body, time), T time body)
viewR :: T time body -> Maybe (T time body, (body, time))
switchL :: c -> (body -> time -> T time body -> c) -> T time body -> c
switchR :: c -> (T time body -> body -> time -> c) -> T time body -> c
span :: (body -> Bool) -> T time body -> (T time body, T time body)


module Data.EventList.Absolute.TimeMixed
snocBody :: T time body -> body -> T time body
snocTime :: T time body -> time -> T time body
viewTimeR :: T time body -> (T time body, time)
viewBodyR :: T time body -> Maybe (T time body, body)
switchTimeR :: (T time body -> time -> a) -> T time body -> a
switchBodyR :: a -> (T time body -> body -> a) -> T time body -> a
mapTimeInit :: (T time body0 -> T time body1) -> T time body0 -> T time body1


module Data.EventList.Absolute.TimeBody
data T time body
empty :: T time body
singleton :: time -> body -> T time body
null :: T time body -> Bool
viewL :: T time body -> Maybe ((time, body), T time body)
viewR :: T time body -> Maybe (T time body, (time, body))
switchL :: c -> ((time, body) -> T time body -> c) -> T time body -> c
switchR :: c -> (T time body -> (time, body) -> c) -> T time body -> c
cons :: time -> body -> T time body -> T time body
snoc :: T time body -> time -> body -> T time body
fromPairList :: [(a, b)] -> T a b
toPairList :: T a b -> [(a, b)]
getTimes :: T time body -> [time]
getBodies :: T time body -> [body]

-- | Duration of an empty event list is considered zero. However, I'm not
--   sure if this is sound.
duration :: Num time => T time body -> time
mapBody :: (body0 -> body1) -> T time body0 -> T time body1
mapTime :: (time0 -> time1) -> T time0 body -> T time1 body
concatMapMonoid :: Monoid m => (time -> m) -> (body -> m) -> T time body -> m
traverse :: Applicative m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)
traverse_ :: Applicative m => (time -> m ()) -> (body -> m ()) -> T time body -> m ()
traverseBody :: Applicative m => (body0 -> m body1) -> T time body0 -> m (T time body1)
traverseTime :: Applicative m => (time0 -> m time1) -> T time0 body -> m (T time1 body)
mapM :: Monad m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)
mapM_ :: Monad m => (time -> m ()) -> (body -> m ()) -> T time body -> m ()
mapBodyM :: Monad m => (body0 -> m body1) -> T time body0 -> m (T time body1)
mapTimeM :: Monad m => (time0 -> m time1) -> T time0 body -> m (T time1 body)

-- | The first important function is <a>merge</a> which merges the events
--   of two lists into a new time order list.
merge :: (Ord time, Ord body) => T time body -> T time body -> T time body

-- | Note that <a>merge</a> compares entire events rather than just start
--   times. This is to ensure that it is commutative, a desirable condition
--   for some of the proofs used in secref{equivalence}. It is also
--   necessary to assert a unique representation of the performance
--   independent of the structure of the 'Music.T note'. The same function
--   for inserting into a time ordered list with a trailing pause. The
--   strictness annotation is necessary for working with infinite lists.
--   
--   Here are two other functions that are already known for non-padded
--   time lists.
mergeBy :: Ord time => (body -> body -> Bool) -> T time body -> T time body -> T time body

-- | The final critical function is <tt>insert</tt>, which inserts an event
--   into an already time-ordered sequence of events. For instance it is
--   used in MidiFiles to insert a <tt>NoteOff</tt> event into a list of
--   <tt>NoteOn</tt> and <tt>NoteOff</tt> events.
insert :: (Ord time, Ord body) => time -> body -> T time body -> T time body
insertBy :: Ord time => (body -> body -> Bool) -> time -> body -> T time body -> T time body

-- | Move events towards the front of the event list. You must make sure,
--   that no event is moved before time zero. This works only for finite
--   lists.
moveForward :: (Ord time, Num time) => T time (time, body) -> T time body
decreaseStart :: (Ord time, Num time) => time -> T time body -> T time body
delay :: (Ord time, Num time) => time -> T time body -> T time body
filter :: Num time => (body -> Bool) -> T time body -> T time body
partition :: (body -> Bool) -> T time body -> (T time body, T time body)
partitionMaybe :: (body0 -> Maybe body1) -> T time body0 -> (T time body1, T time body0)

-- | Since we need it later for MIDI generation, we will also define a
--   slicing into equivalence classes of events.
slice :: Eq a => (body -> a) -> T time body -> [(a, T time body)]
foldr :: (time -> a -> b) -> (body -> b -> a) -> b -> T time body -> b
foldrPair :: (time -> body -> a -> a) -> a -> T time body -> a
mapMaybe :: Num time => (body0 -> Maybe body1) -> T time body0 -> T time body1
catMaybes :: Num time => T time (Maybe body) -> T time body

-- | <a>sort</a> sorts a list of coinciding events, that is all events but
--   the first one have time difference 0. <a>normalize</a> sorts all
--   coinciding events in a list thus yielding a canonical representation
--   of a time ordered list.
normalize :: (Ord time, Num time, Ord body) => T time body -> T time body
isNormalized :: (Ord time, Num time, Ord body) => T time body -> Bool

-- | We will also sometimes need a function which groups events by equal
--   start times. This implementation is not so obvious since we work with
--   time differences. The criterion is: Two neighbouring events start at
--   the same time if the second one has zero time difference.
collectCoincident :: Eq time => T time body -> T time [body]
flatten :: (Ord time, Num time) => T time [body] -> T time body

-- | Apply a function to the lists of coincident events.
mapCoincident :: (Ord time, Num time) => ([a] -> [b]) -> T time a -> T time b
append :: (Ord time, Num time) => T time body -> T time body -> T time body
concat :: (Ord time, Num time) => [T time body] -> T time body
cycle :: (Ord time, Num time) => T time body -> T time body

-- | Here are some functions for discretizing the time information. When
--   converting the precise relative event times to the integer relative
--   event times we have to prevent accumulation of rounding errors. We
--   avoid this problem with a stateful conversion which remembers each
--   rounding error we make. This rounding error is used to correct the
--   next rounding. Given the relative time and duration of a note the
--   function <tt>discretizeEventM</tt> creates a <tt>State</tt> which
--   computes the rounded relative time. It is corrected by previous
--   rounding errors.
--   
--   The resulting event list may have differing time differences which
--   were equal before discretization, but the overall timing is uniformly
--   close to the original.
discretize :: (RealFrac time, Integral i) => T time body -> T i body
resample :: (RealFrac time, Integral i) => time -> T time body -> T i body

-- | Check whether time values are in ascending order. The list is
--   processed lazily and times that are smaller than there predecessors
--   are replaced by <a>undefined</a>. If you would remove the
--   <a>undefined</a> times from the resulting list the times may still not
--   be ordered. E.g. consider the time list <tt>[0,3,1,2]</tt>
checkTimes :: Ord time => T time body -> T time body
collectCoincidentFoldr :: Eq time => T time body -> T time [body]

-- | Will fail on infinite lists.
collectCoincidentNonLazy :: Eq time => T time body -> T time [body]


-- | Event list with absolute times starting with a time and ending with a
--   body
module Data.EventList.Absolute.TimeTime
data T time body
pause :: time -> T time body
isPause :: T time body -> Bool
viewL :: T time body -> (time, Maybe (body, T time body))
switchL :: (time -> a) -> ((time, body) -> T time body -> a) -> T time body -> a
cons :: time -> body -> T time body -> T time body
snoc :: T time body -> body -> time -> T time body
mapBody :: (body0 -> body1) -> T time body0 -> T time body1
mapTime :: (time0 -> time1) -> T time0 body -> T time1 body
concatMapMonoid :: Monoid m => (time -> m) -> (body -> m) -> T time body -> m
traverse :: Applicative m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)
traverse_ :: Applicative m => (time -> m ()) -> (body -> m ()) -> T time body -> m ()
traverseBody :: Applicative m => (body0 -> m body1) -> T time body0 -> m (T time body1)
traverseTime :: Applicative m => (time0 -> m time1) -> T time0 body -> m (T time1 body)
mapM :: Monad m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)
mapM_ :: Monad m => (time -> m ()) -> (body -> m ()) -> T time body -> m ()
mapBodyM :: Monad m => (body0 -> m body1) -> T time body0 -> m (T time body1)
mapTimeM :: Monad m => (time0 -> m time1) -> T time0 body -> m (T time1 body)
getTimes :: T time body -> [time]
getBodies :: T time body -> [body]
duration :: Num time => T time body -> time
merge :: (Ord time, Ord body) => T time body -> T time body -> T time body
mergeBy :: Ord time => (body -> body -> Bool) -> T time body -> T time body -> T time body
insert :: (Ord time, Ord body) => time -> body -> T time body -> T time body
insertBy :: Ord time => (body -> body -> Bool) -> time -> body -> T time body -> T time body

-- | Move events towards the front of the event list. You must make sure,
--   that no event is moved before time zero. This works only for finite
--   lists.
moveForward :: (Ord time, Num time) => T time (time, body) -> T time body
decreaseStart :: (Ord time, Num time) => time -> T time body -> T time body
delay :: (Ord time, Num time) => time -> T time body -> T time body
filter :: Num time => (body -> Bool) -> T time body -> T time body
partition :: (body -> Bool) -> T time body -> (T time body, T time body)
slice :: (Eq a, Num time) => (body -> a) -> T time body -> [(a, T time body)]
foldr :: (time -> a -> b) -> (body -> b -> a) -> a -> T time body -> b
mapMaybe :: Num time => (body0 -> Maybe body1) -> T time body0 -> T time body1
catMaybes :: Num time => T time (Maybe body) -> T time body

-- | <a>sort</a> sorts a list of coinciding events, that is all events but
--   the first one have time difference 0. <a>normalize</a> sorts all
--   coinciding events in a list thus yielding a canonical representation
--   of a time ordered list.
normalize :: (Ord time, Num time, Ord body) => T time body -> T time body
isNormalized :: (Ord time, Num time, Ord body) => T time body -> Bool
collectCoincident :: Eq time => T time body -> T time [body]
flatten :: (Ord time, Num time) => T time [body] -> T time body

-- | Apply a function to the lists of coincident events.
mapCoincident :: (Ord time, Num time) => ([a] -> [b]) -> T time a -> T time b
append :: (Ord time, Num time) => T time body -> T time body -> T time body
concat :: (Ord time, Num time) => [T time body] -> T time body
cycle :: (Ord time, Num time) => T time body -> T time body
discretize :: (RealFrac time, Integral i) => T time body -> T i body
resample :: (RealFrac time, Integral i) => time -> T time body -> T i body


-- | Event lists starting with a time difference and ending with a body.
--   
--   The time is stored in differences between the events. Thus there is no
--   increase of time information for long, or even infinite, streams of
--   events. Further on, the time difference is stored in the latter of two
--   neighbouring events. This is necessary for real-time computing where
--   it is not known whether and when the next event happens.
module Data.EventList.Relative.TimeBody
data T time body
empty :: T time body
singleton :: time -> body -> T time body
null :: T time body -> Bool
viewL :: T time body -> Maybe ((time, body), T time body)
viewR :: T time body -> Maybe (T time body, (time, body))
switchL :: c -> ((time, body) -> T time body -> c) -> T time body -> c
switchR :: c -> (T time body -> (time, body) -> c) -> T time body -> c
cons :: time -> body -> T time body -> T time body
snoc :: T time body -> time -> body -> T time body
fromPairList :: [(a, b)] -> T a b
toPairList :: T a b -> [(a, b)]
getTimes :: T time body -> [time]
getBodies :: T time body -> [body]
duration :: C time => T time body -> time
mapBody :: (body0 -> body1) -> T time body0 -> T time body1
mapTime :: (time0 -> time1) -> T time0 body -> T time1 body
zipWithBody :: (body0 -> body1 -> body2) -> [body0] -> T time body1 -> T time body2
zipWithTime :: (time0 -> time1 -> time2) -> [time0] -> T time1 body -> T time2 body
unzip :: T time (body0, body1) -> (T time body0, T time body1)
concatMapMonoid :: Monoid m => (time -> m) -> (body -> m) -> T time body -> m
traverse :: Applicative m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)
traverse_ :: Applicative m => (time -> m ()) -> (body -> m ()) -> T time body -> m ()
traverseBody :: Applicative m => (body0 -> m body1) -> T time body0 -> m (T time body1)
traverseTime :: Applicative m => (time0 -> m time1) -> T time0 body -> m (T time1 body)
mapM :: Monad m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)
mapM_ :: Monad m => (time -> m ()) -> (body -> m ()) -> T time body -> m ()
mapBodyM :: Monad m => (body0 -> m body1) -> T time body0 -> m (T time body1)
mapTimeM :: Monad m => (time0 -> m time1) -> T time0 body -> m (T time1 body)
foldr :: (time -> a -> b) -> (body -> b -> a) -> b -> T time body -> b
foldrPair :: (time -> body -> a -> a) -> a -> T time body -> a

-- | This function merges the events of two lists into a new event list.
--   Note that <a>merge</a> compares entire events rather than just start
--   times. This is to ensure that it is commutative, one of the properties
--   we test for.
merge :: (C time, Ord body) => T time body -> T time body -> T time body

-- | <a>mergeBy</a> is like <a>merge</a> but does not simply use the
--   methods of the <a>Ord</a> class but allows a custom comparison
--   function. If in event lists <tt>xs</tt> and <tt>ys</tt> there are
--   coinciding elements <tt>x</tt> and <tt>y</tt>, and <tt>cmp x y</tt> is
--   <a>True</a>, then <tt>x</tt> comes before <tt>y</tt> in <tt>mergeBy
--   cmp xs ys</tt>.
--   
--   <pre>
--   EventList&gt; EventList.mergeBy (\_ _ -&gt; True) (0 /. 'a' ./ empty) (0 /. 'b' ./ empty)
--   0 /. 'a' ./ 0 /. 'b' ./ empty
--   
--   EventList&gt; EventList.mergeBy (\_ _ -&gt; False) (0 /. 'a' ./ empty) (0 /. 'b' ./ empty)
--   0 /. 'b' ./ 0 /. 'a' ./ empty
--   </pre>
mergeBy :: C time => (body -> body -> Bool) -> T time body -> T time body -> T time body

-- | <a>insert</a> inserts an event into an event list at the given time.
insert :: (C time, Ord body) => time -> body -> T time body -> T time body
insertBy :: C time => (body -> body -> Bool) -> time -> body -> T time body -> T time body

-- | Move events towards the front of the event list. You must make sure,
--   that no event is moved before time zero. This works only for finite
--   lists.
moveForward :: (Ord time, Num time) => T time (time, body) -> T time body
decreaseStart :: C time => time -> T time body -> T time body
delay :: C time => time -> T time body -> T time body

-- | Keep only events that match a predicate while preserving absolute
--   times.
filter :: C time => (body -> Bool) -> T time body -> T time body
partition :: C time => (body -> Bool) -> T time body -> (T time body, T time body)
partitionMaybe :: C time => (body0 -> Maybe body1) -> T time body0 -> (T time body1, T time body0)

-- | Using a classification function we splice the event list into lists,
--   each containing the same class. Absolute time stamps are preserved.
slice :: (Eq a, C time) => (body -> a) -> T time body -> [(a, T time body)]
span :: (body -> Bool) -> T time body -> (T time body, T time body)
mapMaybe :: C time => (body0 -> Maybe body1) -> T time body0 -> T time body1

-- | Adds times in a left-associative fashion. Use this if the time is a
--   strict data type.
catMaybes :: C time => T time (Maybe body) -> T time body

-- | <a>sort</a> sorts a list of coinciding events, that is all events but
--   the first one have time difference 0. <a>normalize</a> sorts all
--   coinciding events in a list thus yielding a canonical representation
--   of a time ordered list.
normalize :: (C time, Ord body) => T time body -> T time body
isNormalized :: (C time, Ord body) => T time body -> Bool

-- | Group events that have equal start times (that is zero time
--   differences).
collectCoincident :: C time => T time body -> T time [body]

-- | Reverse to collectCoincident: Turn each <tt>body</tt> into a separate
--   event.
--   
--   <pre>
--   xs  ==  flatten (collectCoincident xs)
--   </pre>
flatten :: C time => T time [body] -> T time body

-- | Apply a function to the lists of coincident events.
mapCoincident :: C time => ([a] -> [b]) -> T time a -> T time b
append :: T time body -> T time body -> T time body
concat :: [T time body] -> T time body
cycle :: T time body -> T time body

-- | We provide <a>discretize</a> and <a>resample</a> for discretizing the
--   time information. When converting the precise relative event times to
--   the integer relative event times we have to prevent accumulation of
--   rounding errors. We avoid this problem with a stateful conversion
--   which remembers each rounding error we make. This rounding error is
--   used to correct the next rounding. Given the relative time and
--   duration of an event the function <tt>floorDiff</tt> creates a
--   <a>State</a> which computes the rounded relative time. It is corrected
--   by previous rounding errors.
--   
--   The resulting event list may have differing time differences which
--   were equal before discretization, but the overall timing is uniformly
--   close to the original.
--   
--   We use <tt>floorDiff</tt> rather than <a>roundDiff</a> in order to
--   compute exclusively with non-negative numbers.
discretize :: (C time, RealFrac time, C i, Integral i) => T time body -> T i body
resample :: (C time, RealFrac time, C i, Integral i) => time -> T time body -> T i body

-- | We tried hard to compute everything with respect to relative times.
--   However sometimes we need absolute time values.
toAbsoluteEventList :: Num time => time -> T time body -> T time body
fromAbsoluteEventList :: Num time => T time body -> T time body


-- | Event lists starting with a time difference and ending with a time
--   difference.
module Data.EventList.Relative.TimeTime
data T time body
mapBody :: (body0 -> body1) -> T time body0 -> T time body1
mapTime :: (time0 -> time1) -> T time0 body -> T time1 body
zipWithBody :: (body0 -> body1 -> body2) -> [body0] -> T time body1 -> T time body2
zipWithTime :: (time0 -> time1 -> time2) -> (time0, [time0]) -> T time1 body -> T time2 body
unzip :: T time (body0, body1) -> (T time body0, T time body1)
concatMapMonoid :: Monoid m => (time -> m) -> (body -> m) -> T time body -> m
traverse :: Applicative m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)
traverse_ :: Applicative m => (time -> m ()) -> (body -> m ()) -> T time body -> m ()
traverseBody :: Applicative m => (body0 -> m body1) -> T time body0 -> m (T time body1)
traverseTime :: Applicative m => (time0 -> m time1) -> T time0 body -> m (T time1 body)
mapM :: Monad m => (time0 -> m time1) -> (body0 -> m body1) -> T time0 body0 -> m (T time1 body1)
mapM_ :: Monad m => (time -> m ()) -> (body -> m ()) -> T time body -> m ()
mapBodyM :: Monad m => (body0 -> m body1) -> T time body0 -> m (T time body1)
mapTimeM :: Monad m => (time0 -> m time1) -> T time0 body -> m (T time1 body)
getTimes :: T time body -> [time]
getBodies :: T time body -> [body]
duration :: C time => T time body -> time

-- | The first important function is <a>merge</a> which merges the events
--   of two lists into a new time order list.
merge :: (C time, Ord body) => T time body -> T time body -> T time body
mergeBy :: C time => (body -> body -> Bool) -> T time body -> T time body -> T time body

-- | Note that <a>merge</a> compares entire events rather than just start
--   times. This is to ensure that it is commutative, a desirable condition
--   for some of the proofs used in Haskore/section equivalence. It is also
--   necessary to assert a unique representation of the event list
--   independent of the structure of the event type. The same function for
--   inserting into a time ordered list with a trailing pause.
insert :: (C time, Ord body) => time -> body -> T time body -> T time body
pad :: C time => time -> T time body -> T time body

-- | Move events towards the front of the event list. You must make sure,
--   that no event is moved before time zero. This works only for finite
--   lists.
moveForward :: (Ord time, Num time) => T time (time, body) -> T time body

-- | Like <a>moveForward</a> but restricts the look-ahead time. For
--   <tt>moveForwardRestricted maxTimeDiff xs</tt> all time differences
--   (aka the moveForward offsets) in <tt>xs</tt> must be at most
--   <tt>maxTimeDiff</tt>. With this restriction the function is lazy
--   enough for handling infinite event lists. However the larger
--   <tt>maxTimeDiff</tt> the more memory and time is consumed.
moveForwardRestricted :: (Ord body, C time) => time -> T time (time, body) -> T time body
moveBackward :: C time => T time (time, body) -> T time body

-- | Merge several event lists respecting the start time of the outer event
--   list.
arrange :: (Ord body, C time) => T time (T time body) -> T time body
arrangeBy :: C time => (body -> body -> Bool) -> T time (T time body) -> T time body

-- | currently only for testing
moveForwardRestrictedBy :: C time => (body -> body -> Bool) -> time -> T time (time, body) -> T time body

-- | currently only for testing
moveForwardRestrictedByQueue :: (C time, Num time) => (body -> body -> Bool) -> time -> T time (time, body) -> T time body

-- | currently only for testing
moveForwardRestrictedByStrict :: C time => (body -> body -> Bool) -> time -> T time (time, body) -> T time body
decreaseStart :: C time => time -> T time body -> T time body
delay :: C time => time -> T time body -> T time body

-- | Analogously to the <a>concat</a> / <a>concatNaive</a> pair we have to
--   versions of <a>filter</a>, where the clever implementation sums up
--   pauses from the beginning to the end.
filter :: C time => (body -> Bool) -> T time body -> T time body
partition :: C time => (body -> Bool) -> T time body -> (T time body, T time body)
partitionMaybe :: C time => (body0 -> Maybe body1) -> T time body0 -> (T time body1, T time body0)

-- | Cf. <a>catMaybesR</a>
partitionMaybeR :: C time => (body0 -> Maybe body1) -> T time body0 -> (T time body1, T time body0)

-- | Since we need it later for MIDI generation, we will also define a
--   slicing into equivalence classes of events.
slice :: (Eq a, C time) => (body -> a) -> T time body -> [(a, T time body)]
foldr :: (time -> a -> b) -> (body -> b -> a) -> a -> T time body -> b
foldl :: (a -> time -> b) -> (b -> body -> a) -> a -> T time body -> b
pause :: time -> T time body
isPause :: T time body -> Bool
cons :: time -> body -> T time body -> T time body
snoc :: T time body -> body -> time -> T time body
viewL :: T time body -> (time, Maybe (body, T time body))
viewR :: T time body -> (Maybe (T time body, body), time)
switchL :: (time -> a) -> ((time, body) -> T time body -> a) -> T time body -> a
switchR :: (time -> a) -> (T time body -> body -> time -> a) -> T time body -> a
mapMaybe :: C time => (body0 -> Maybe body1) -> T time body0 -> T time body1

-- | Adds times in a left-associative fashion. Use this if the time is a
--   strict data type.
catMaybes :: C time => T time (Maybe body) -> T time body

-- | Adds times in a right-associative fashion. Use this if the time is a
--   data type like lazy Peano numbers or
--   <a>Numeric.NonNegative.Chunky</a>.
catMaybesR :: C time => T time (Maybe body) -> T time body
append :: C time => T time body -> T time body -> T time body
concat :: C time => [T time body] -> T time body

-- | <a>concat</a> and <a>concatNaive</a> are essentially the same.
--   <a>concat</a> must use <a>foldr</a> in order to work on infinite
--   lists, however if there are many empty lists, summing of their
--   durations will be done from right to left, which is inefficient. Thus
--   we detect subsequent empty lists and merge them from left to right.
concatNaive :: C time => [T time body] -> T time body

-- | Uses sharing.
cycle :: C time => T time body -> T time body
cycleNaive :: C time => T time body -> T time body
reverse :: T time body -> T time body

-- | If there is an event at the cutting time, this event is returned in
--   the suffix part. That is <tt>splitAtTime t0 (t0 .<i> x </i>. t1 ./
--   empty) == (pause t0, 0 .<i> x </i>. t1 ./ empty)</tt>
splitAtTime :: C time => time -> T time body -> (T time body, T time body)
takeTime :: C time => time -> T time body -> T time body
dropTime :: C time => time -> T time body -> T time body
forceTimeHead :: C time => T time body -> T time body
discretize :: (C time, RealFrac time, C i, Integral i) => T time body -> T i body
resample :: (C time, RealFrac time, C i, Integral i) => time -> T time body -> T i body
collectCoincident :: C time => T time body -> T time [body]
flatten :: C time => T time [body] -> T time body
mapCoincident :: C time => ([a] -> [b]) -> T time a -> T time b

-- | Sort coincident elements.
normalize :: (Ord body, C time) => T time body -> T time body
isNormalized :: (C time, Ord body) => T time body -> Bool
toAbsoluteEventList :: Num time => time -> T time body -> T time body
fromAbsoluteEventList :: Num time => T time body -> T time body


-- | Event lists starting with a body and ending with a time difference.
module Data.EventList.Relative.MixedTime
consBody :: body -> T time body -> T time body
consTime :: time -> T time body -> T time body
(/.) :: time -> T time body -> T time body
(./) :: body -> T time body -> T time body
empty :: T time body
viewTimeL :: T time body -> (time, T time body)
viewBodyL :: T time body -> Maybe (body, T time body)
switchTimeL :: (time -> T time body -> a) -> T time body -> a
switchBodyL :: a -> (body -> T time body -> a) -> T time body -> a
mapTimeL :: (time -> time, T time body0 -> T time body1) -> T time body0 -> T time body1
mapTimeHead :: (time -> time) -> T time body -> T time body
mapTimeTail :: (T time body0 -> T time body1) -> T time body0 -> T time body1
mapBodyL :: (body -> body, T time0 body -> T time1 body) -> T time0 body -> T time1 body
mapBodyHead :: (body -> body) -> T time body -> T time body
mapBodyTail :: (T time0 body -> T time1 body) -> T time0 body -> T time1 body


-- | Event lists starting with a body and ending with a time difference.
module Data.EventList.Relative.TimeMixed
snocBody :: T time body -> body -> T time body
snocTime :: T time body -> time -> T time body
viewTimeR :: T time body -> (T time body, time)
viewBodyR :: T time body -> Maybe (T time body, body)
switchTimeR :: (T time body -> time -> a) -> T time body -> a
switchBodyR :: a -> (T time body -> body -> a) -> T time body -> a
mapTimeR :: (T time body0 -> T time body1, time -> time) -> T time body0 -> T time body1
mapTimeLast :: (time -> time) -> T time body -> T time body
mapTimeInit :: (T time body0 -> T time body1) -> T time body0 -> T time body1
mapBodyR :: (T time0 body -> T time1 body, body -> body) -> T time0 body -> T time1 body
mapBodyLast :: (body -> body) -> T time body -> T time body
mapBodyInit :: (T time0 body -> T time1 body) -> T time0 body -> T time1 body

-- | This is not a good name, expect a change.
appendBodyEnd :: C time => T time body -> T time body -> T time body

-- | This is not a good name, expect a change.
prependBodyEnd :: T time body -> T time body -> T time body
splitAtTime :: C time => time -> T time body -> (T time body, T time body)
takeTime :: C time => time -> T time body -> T time body
dropTime :: C time => time -> T time body -> T time body


-- | Event lists starting with a body and ending with a time difference.
module Data.EventList.Relative.MixedBody
consBody :: body -> T time body -> T time body
consTime :: time -> T time body -> T time body
(/.) :: time -> T time body -> T time body
(./) :: body -> T time body -> T time body
empty :: T time body
viewTimeL :: T time body -> Maybe (time, T time body)
viewBodyL :: T time body -> (body, T time body)
switchTimeL :: a -> (time -> T time body -> a) -> T time body -> a
switchBodyL :: (body -> T time body -> a) -> T time body -> a
mapTimeL :: (time -> time, T time body0 -> T time body1) -> T time body0 -> T time body1
mapTimeHead :: (time -> time) -> T time body -> T time body
mapTimeTail :: (T time body0 -> T time body1) -> T time body0 -> T time body1
