{- |
Copyright   :  (c) Henning Thielemann 2007

Maintainer  :  haskell@henning-thielemann.de
Stability   :  stable
Portability :  Haskell 98
-}
module Data.EventList.Relative.BodyTimePrivate where

import qualified Data.AlternatingList.List.Disparate as Disp
-- import qualified Data.AlternatingList.List.Uniform as Uniform
import qualified Data.AlternatingList.List.Mixed as Mixed

import qualified Control.Monad as Monad

import Test.QuickCheck (Arbitrary(..))



newtype T time body = Cons {decons :: Disp.T body time}
   deriving (Eq, Ord)

instance (Show time, Show body) => Show (T time body) where
   showsPrec p = Disp.format " ./ " " /. " p . decons


instance (Arbitrary time, Arbitrary body) =>
             Arbitrary (T time body) where
   arbitrary = Monad.liftM Cons arbitrary
   coarbitrary = undefined


infixl 5 $*~

($*~) :: (Disp.T body time -> a) -> (T time body -> a)
($*~) f = f . decons


lift ::
   (Disp.T body0 time0 -> Disp.T body1 time1) ->
   (T time0 body0 -> T time1 body1)
lift f = Cons . f . decons

liftM :: Monad m =>
   (Disp.T body0 time0 -> m (Disp.T body1 time1)) ->
   (T time0 body0 -> m (T time1 body1))
liftM f = Monad.liftM Cons . f . decons

unlift ::
   (T time0 body0 -> T time1 body1) ->
   (Disp.T body0 time0 -> Disp.T body1 time1)
unlift f = decons . f . Cons



concat :: -- (NonNeg.C time) =>
   [T time body] -> T time body
concat =
   Cons . Disp.concat . map decons


cycle :: -- (NonNeg.C time) =>
   T time body -> T time body
cycle = lift Disp.cycle


mapTimeLast ::
   (time -> time) ->
   T time body -> T time body
mapTimeLast = lift . Mixed.mapFirstLast