\subsubsection{Time ordered lists with trailing rests}

This module is very similar to \module{TimeOrderedList},
but it supports a trailing pause.
Essentially all functions of \module{TimeOrderedList}
should behave like their counterparts in this module,
if the trailing rest is ignored or set to zero.

\begin{haskelllisting}

> module Haskore.Basic.TimeOrderedListPad
>    (T,
>     mapBody, mapTime, mapM, mapM_,
>     BodyTimeList.empty, pause,
>     merge, insert, decreaseStart, delay, filter, foldr,
>     viewTimeL, viewBodyL, viewTimeR, viewBodyR, {- viewR, -}
>     cons, consBody, consTime,
>     snoc, snocBody, snocTime,
>     mapTimeL, mapTimeHead, mapTimeTail,
>     mapBodyL, mapBodyHead, mapBodyTail,
>     mapTimeR, mapTimeLast, mapTimeInit,
>     mapBodyR, mapBodyLast, mapBodyInit,
>     catMaybes,
>     append,
>     concat, concatNaive, resample,
>     toAbsoluteEventList,
>     run, runTimeStamp, runTimeStampGrouped, runRelative,
>     collectCoincident, flatten, mapCoincident,
>    ) where
>
> import Data.EventList.Relative.TimeTime
> import Data.EventList.Relative.MixedTime
> import Data.EventList.Relative.TimeMixed
> import qualified Data.EventList.Relative.BodyTime as BodyTimeList
> import qualified Data.EventList.Absolute.TimeTime as AbsList
> import qualified Data.EventList.Absolute.TimeMixed as AbsListMix
>
> import qualified Haskore.Basic.Timer as Timer
> import qualified Haskore.Basic.TimeOrderedList as TimeList
> import qualified Numeric.NonNegative.Class as NonNeg
> -- import qualified Numeric.NonNegative.Wrapper as NonNegW
>
> import qualified Control.Monad as Monad
> import Control.Monad.Trans (MonadIO, liftIO)

> import Prelude hiding (concat, filter, foldr, mapM, mapM_)

\end{haskelllisting}


\begin{haskelllisting}

> runRelative :: (NonNeg.C time, RealFrac time, MonadIO io) =>
>    Timer.T -> (body -> io a) -> T time body -> io [a]
> runRelative timer action =
>    Monad.liftM getBodies .
>    mapM (liftIO . Timer.wait timer) action .
>    resample (fromIntegral $ Timer.resolution timer)

\end{haskelllisting}

\begin{haskelllisting}

> run :: (RealFrac time, MonadIO io) =>
>    Timer.T -> (body -> io a) -> T time body -> io [a]
> run timer action = runTimeStamp timer (const action)

> runTimeStamp :: (RealFrac time, MonadIO io) =>
>    Timer.T -> (time -> body -> io a) -> T time body -> io [a]
> runTimeStamp =
>    runCore id

> runTimeStampGrouped :: (RealFrac time, MonadIO io) =>
>    Timer.T -> (time -> [body] -> io a) -> T time body -> io [a]
> runTimeStampGrouped =
>    runCore AbsList.collectCoincident

> runCore :: (Fractional time0, RealFrac time1, MonadIO io) =>
>    (AbsList.T time0 body0 -> AbsList.T time1 body1) ->
>    Timer.T -> (time1 -> body1 -> io a) -> T time0 body0 -> io [a]
> runCore convertAbs timer action evs =
>    Monad.liftM AbsList.getBodies .
>    AbsList.mapM
>       (liftIO . Timer.waitUntilSeconds timer)
>       (uncurry action) .
>    attachTime .
>    convertAbs .
>    flip toAbsoluteEventList evs =<<
>    liftIO (Timer.getTimeSeconds timer)

> attachTime :: AbsList.T time body -> AbsList.T time (time, body)
> attachTime =
>    AbsListMix.mapTimeInit TimeList.attachTime

\end{haskelllisting}




% *Haskore.Basic.TimeOrderedListPad Haskore.Basic.Timer.Thread> runRelative Haskore.Basic.Timer.Thread.timer print $ 0.1 /. 'a' ./ (0.1::Numeric.NonNegative.Wrapper.Double) /. 'b' ./ undefined
%
% *Haskore.Basic.TimeOrderedListPad Haskore.Basic.Timer.Thread> runTimeStamp Haskore.Basic.Timer.Thread.timer (\t b -> print (t,b)) $ 0.1 /. 'a' ./ 0.1 /. 'b' ./ undefined
% (1.1966023807219398e9,'a')
% (1.1966023808219397e9,*** Exception: Prelude.undefined
