packages feed

event-list 0.0.11.1 → 0.1

raw patch · 14 files changed

+606/−312 lines, 14 filesdep ~non-negativePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: non-negative

API changes (from Hackage documentation)

- Data.EventList.Relative.MixedBody: (./) :: body -> T time body -> T time body
- Data.EventList.Relative.MixedBody: (/.) :: time -> T time body -> T time body
- Data.EventList.Relative.MixedBody: consBody :: body -> T time body -> T time body
- Data.EventList.Relative.MixedBody: consTime :: time -> T time body -> T time body
+ Data.EventList.Relative.MixedBody: consBody, ./ :: body -> T time body -> T time body
+ Data.EventList.Relative.MixedBody: consTime, /. :: time -> T time body -> T time body
+ Data.EventList.Relative.TimeBody: unzip :: T time (body0, body1) -> (T time body0, T time body1)
+ Data.EventList.Relative.TimeTime: forceTimeHead :: C time => T time body -> T time body
+ Data.EventList.Relative.TimeTime: unzip :: T time (body0, body1) -> (T time body0, T time body1)
- Data.EventList.Relative.TimeBody: catMaybes :: Num time => T time (Maybe body) -> T time body
+ Data.EventList.Relative.TimeBody: catMaybes :: C time => T time (Maybe body) -> T time body
- Data.EventList.Relative.TimeBody: duration :: Num time => T time body -> time
+ Data.EventList.Relative.TimeBody: duration :: C time => T time body -> time
- Data.EventList.Relative.TimeBody: filter :: Num time => (body -> Bool) -> T time body -> T time body
+ Data.EventList.Relative.TimeBody: filter :: C time => (body -> Bool) -> T time body -> T time body
- Data.EventList.Relative.TimeBody: mapMaybe :: Num time => (body0 -> Maybe body1) -> T time body0 -> T time body1
+ Data.EventList.Relative.TimeBody: mapMaybe :: C time => (body0 -> Maybe body1) -> T time body0 -> T time body1
- Data.EventList.Relative.TimeBody: moveForward :: C time => T time (time, body) -> T time body
+ Data.EventList.Relative.TimeBody: moveForward :: (Ord time, Num time) => T time (time, body) -> T time body
- Data.EventList.Relative.TimeBody: partition :: Num time => (body -> Bool) -> T time body -> (T time body, T time body)
+ Data.EventList.Relative.TimeBody: partition :: C time => (body -> Bool) -> T time body -> (T time body, T time body)
- Data.EventList.Relative.TimeBody: partitionMaybe :: Num time => (body0 -> Maybe body1) -> T time body0 -> (T time body1, T time body0)
+ Data.EventList.Relative.TimeBody: partitionMaybe :: C time => (body0 -> Maybe body1) -> T time body0 -> (T time body1, T time body0)
- Data.EventList.Relative.TimeBody: slice :: (Eq a, Num time) => (body -> a) -> T time body -> [(a, T time body)]
+ Data.EventList.Relative.TimeBody: slice :: (Eq a, C time) => (body -> a) -> T time body -> [(a, T time body)]
- Data.EventList.Relative.TimeTime: catMaybes :: Num time => T time (Maybe body) -> T time body
+ Data.EventList.Relative.TimeTime: catMaybes :: C time => T time (Maybe body) -> T time body
- Data.EventList.Relative.TimeTime: catMaybesR :: Num time => T time (Maybe body) -> T time body
+ Data.EventList.Relative.TimeTime: catMaybesR :: C time => T time (Maybe body) -> T time body
- Data.EventList.Relative.TimeTime: duration :: Num time => T time body -> time
+ Data.EventList.Relative.TimeTime: duration :: C time => T time body -> time
- Data.EventList.Relative.TimeTime: filter :: Num time => (body -> Bool) -> T time body -> T time body
+ Data.EventList.Relative.TimeTime: filter :: C time => (body -> Bool) -> T time body -> T time body
- Data.EventList.Relative.TimeTime: flatten :: Num time => T time [body] -> T time body
+ Data.EventList.Relative.TimeTime: flatten :: C time => T time [body] -> T time body
- Data.EventList.Relative.TimeTime: mapMaybe :: Num time => (body0 -> Maybe body1) -> T time body0 -> T time body1
+ Data.EventList.Relative.TimeTime: mapMaybe :: C time => (body0 -> Maybe body1) -> T time body0 -> T time body1
- Data.EventList.Relative.TimeTime: moveForward :: C time => T time (time, body) -> T time body
+ Data.EventList.Relative.TimeTime: moveForward :: (Ord time, Num time) => T time (time, body) -> T time body
- Data.EventList.Relative.TimeTime: moveForwardRestrictedByQueue :: C time => (body -> body -> Bool) -> time -> T time (time, body) -> T time body
+ Data.EventList.Relative.TimeTime: moveForwardRestrictedByQueue :: (C time, Num time) => (body -> body -> Bool) -> time -> T time (time, body) -> T time body
- Data.EventList.Relative.TimeTime: partition :: Num time => (body -> Bool) -> T time body -> (T time body, T time body)
+ Data.EventList.Relative.TimeTime: partition :: C time => (body -> Bool) -> T time body -> (T time body, T time body)
- Data.EventList.Relative.TimeTime: partitionMaybe :: Num time => (body0 -> Maybe body1) -> T time body0 -> (T time body1, T time body0)
+ Data.EventList.Relative.TimeTime: partitionMaybe :: C time => (body0 -> Maybe body1) -> T time body0 -> (T time body1, T time body0)
- Data.EventList.Relative.TimeTime: partitionMaybeR :: Num time => (body0 -> Maybe body1) -> T time body0 -> (T time body1, T time body0)
+ Data.EventList.Relative.TimeTime: partitionMaybeR :: C time => (body0 -> Maybe body1) -> T time body0 -> (T time body1, T time body0)
- Data.EventList.Relative.TimeTime: slice :: (Eq a, Num time) => (body -> a) -> T time body -> [(a, T time body)]
+ Data.EventList.Relative.TimeTime: slice :: (Eq a, C time) => (body -> a) -> T time body -> [(a, T time body)]

Files

event-list.cabal view
@@ -1,5 +1,5 @@ Name:             event-list-Version:          0.0.11.1+Version:          0.1 License:          GPL License-File:     LICENSE Author:           Henning Thielemann <haskell@henning-thielemann.de>@@ -26,7 +26,7 @@ Source-Repository this   type:     darcs   location: http://code.haskell.org/~thielema/event-list/-  tag:      0.0.11.1+  tag:      0.1  Flag splitBase   description: Choose the new smaller, split-up base package.@@ -37,7 +37,7 @@  Library   Build-Depends:-    non-negative >=0.0 && <0.1,+    non-negative >=0.1 && <0.2,     transformers >=0.1 && <0.3,     utility-ht >=0.0.3 && <0.1,     QuickCheck >=1.1 && <3
src/Data/AlternatingList/List/Mixed.hs view
@@ -117,6 +117,12 @@ {-# INLINE switchSecondL #-} switchSecondL :: (b -> Disp.T a b -> c) -> Uniform.T a b -> c switchSecondL f (Uniform.Cons b xs) = f b xs+{-+The lazy pattern match leads to a space leak in synthesizer-alsa:testArrangeSpaceLeak+I would like to reproduce this in a small test,+but I did not achieve this so far.+-}+-- switchSecondL f ~(Uniform.Cons b xs) = f b xs   {-# INLINE switchR #-}
src/Data/AlternatingList/List/Uniform.hs view
@@ -19,7 +19,8 @@     getFirsts, getSeconds, length, genericLength,     fromFirstList, fromSecondList, fromEitherList,     singleton, isSingleton,-    cons, snoc, reverse, mapSecondHead,+    cons, snoc, reverse,+    mapSecondHead, forceSecondHead,     foldr, foldl,     format,     filterFirst, partitionFirst, partitionMaybeFirst,@@ -201,10 +202,19 @@ mapSecondHead :: (b -> b) -> T a b -> T a b mapSecondHead f ~(Cons b xs) = Cons (f b) xs +forceSecondHead :: T a b -> T a b+forceSecondHead = mapSecondHead id  + foldr :: (a -> c -> d) -> (b -> d -> c) -> d -> T a b -> c foldr f g d (Cons b xs) = g b $ Disp.foldr f g d xs+{-+The lazy pattern match leads to a space leak in synthesizer-alsa:testArrangeSpaceLeak+I would like to reproduce this in a small test,+but I did not achieve this so far.+-}+-- foldr f g d ~(Cons b xs) = g b $ Disp.foldr f g d xs  foldl :: (c -> a -> d) -> (d -> b -> c) -> d -> T a b -> c foldl f g d0 xs =
src/Data/EventList/Absolute/TimeBodyPrivate.hs view
@@ -92,6 +92,10 @@ duration :: Num time => T time body -> time duration = switchR 0 (const fst) +{-+Is it necessary to exclude negative delays?+Even negative time stamps should not hurt absolutely timestamped lists.+-} delay :: (Ord time, Num time) =>    time -> T time body -> T time body delay dif =
src/Data/EventList/Relative/TimeBody.hs view
@@ -25,7 +25,7 @@     fromPairList, toPairList,     getTimes, getBodies, duration,     mapBody, mapTime,-    zipWithBody, zipWithTime,+    zipWithBody, zipWithTime, unzip,     concatMapMonoid,     traverse, traverse_, traverseBody, traverseTime,     mapM, mapM_, mapBodyM, mapTimeM,@@ -58,13 +58,14 @@ import Data.Monoid (Monoid, )  import qualified Numeric.NonNegative.Class as NonNeg+import Numeric.NonNegative.Class ((-|), zero, add, ) import Data.Tuple.HT (mapFst, mapSnd, mapPair, ) import Data.Maybe.HT (toMaybe, ) import Data.List.HT (isAscending, )-import Data.EventList.Utility (floorDiff, beforeBy, ) import Control.Monad.Trans.State (evalState, modify, get, put, ) -import Prelude hiding (mapM, mapM_, null, foldr, filter, concat, cycle, span, )+import Prelude hiding+          (mapM, mapM_, unzip, null, foldr, filter, concat, cycle, span, )   @@ -115,8 +116,8 @@ getTimes :: T time body -> [time] getTimes = Disp.getFirsts . decons -duration :: Num time => T time body -> time-duration = sum . getTimes+duration :: NonNeg.C time => T time body -> time+duration = NonNeg.sum . getTimes   @@ -138,7 +139,15 @@ zipWithTime f = lift . Disp.zipWithFirst f  +unzip :: T time (body0, body1) -> (T time body0, T time body1)+unzip =+   foldrPair+      (\time (body0, body1) ->+         mapPair (cons time body0, cons time body1))+      (empty, empty) ++ concatMapMonoid :: Monoid m =>    (time -> m) -> (body -> m) ->    T time body -> m@@ -200,12 +209,12 @@ {- | Keep only events that match a predicate while preserving absolute times. -}-filter :: (Num time) =>+filter :: (NonNeg.C time) =>    (body -> Bool) -> T time body -> T time body filter p = mapMaybe (\b -> toMaybe (p b) b) -- filter p = fst . partition p -mapMaybe :: (Num time) =>+mapMaybe :: (NonNeg.C time) =>    (body0 -> Maybe body1) ->    T time body0 -> T time body1 mapMaybe f = catMaybes . mapBody f@@ -214,12 +223,12 @@ Adds times in a left-associative fashion. Use this if the time is a strict data type. -}-catMaybes :: (Num time) =>+catMaybes :: (NonNeg.C time) =>    T time (Maybe body) -> T time body catMaybes =    Cons .    fst . Mixed.viewSecondR .-   Uniform.mapSecond sum .+   Uniform.mapSecond NonNeg.sum .    Uniform.catMaybesFirst .    flip Mixed.snocSecond (error "catMaybes: no trailing time") .    decons@@ -254,11 +263,11 @@ {- Could be implemented more easily in terms of Uniform.partition -}-partition :: (Num time) =>+partition :: (NonNeg.C time) =>    (body -> Bool) -> T time body -> (T time body, T time body)-partition p = partitionRec p 0 0+partition p = partitionRec p zero zero -partitionRec :: (Num time) =>+partitionRec :: (NonNeg.C time) =>    (body -> Bool) -> time -> time ->        T time body -> (T time body, T time body) partitionRec p =@@ -266,14 +275,14 @@           switchL              (empty, empty)              (\ (t, b) es ->-                let t0' = t0 + t-                    t1' = t1 + t+                let t0' = add t0 t+                    t1' = add t1 t                 in  if p b-                      then mapFst (cons t0' b) (recourse 0 t1' es)-                      else mapSnd (cons t1' b) (recourse t0' 0 es))+                      then mapFst (cons t0' b) (recourse zero t1' es)+                      else mapSnd (cons t1' b) (recourse t0' zero es))    in  recourse -partitionMaybe :: (Num time) =>+partitionMaybe :: (NonNeg.C time) =>    (body0 -> Maybe body1) -> T time body0 ->    (T time body1, T time body0) partitionMaybe f =@@ -289,7 +298,7 @@ we splice the event list into lists, each containing the same class. Absolute time stamps are preserved. -}-slice :: (Eq a, Num time) =>+slice :: (Eq a, NonNeg.C time) =>    (body -> a) -> T time body -> [(a, T time body)] slice = Utility.slice (fmap (snd . fst) . viewL) partition @@ -304,7 +313,7 @@ -} collectCoincident :: (NonNeg.C time) => T time body -> T time [body] collectCoincident =-   mapTimeTail $ BodyBodyPriv.lift $ Uniform.filterFirst (0<)+   mapTimeTail $ BodyBodyPriv.lift $ Uniform.filterFirst (zero <)  {- | Reverse to collectCoincident:@@ -321,9 +330,9 @@          unlift (delay time) .          fst . Mixed.viewSecondR .          Uniform.foldr-            (Mixed.appendUniformUniform . Uniform.fromSecondList 0)+            (Mixed.appendUniformUniform . Uniform.fromSecondList zero)             Mixed.consSecond Disp.empty .-         Uniform.mapSecond sum .+         Uniform.mapSecond NonNeg.sum .          Uniform.filterSecond (not . List.null)) .    decons @@ -372,29 +381,26 @@ mergeBy :: (NonNeg.C time) =>    (body -> body -> Bool) ->    T time body -> T time body -> T time body-mergeBy before xs0 ys0 =-   case (viewL xs0, viewL ys0) of-      (Nothing, _) -> ys0-      (_, Nothing) -> xs0-      (Just (x@(xt,xb),xs), Just (y@(yt,yb),ys)) ->-         if beforeBy before x y-           then uncurry cons x $ mergeBy before xs $ cons (yt-xt) yb ys-           else uncurry cons y $ mergeBy before ys $ cons (xt-yt) xb xs+mergeBy before =+   let recourse xs0 ys0 =+          case (viewL xs0, viewL ys0) of+             (Nothing, _) -> ys0+             (_, Nothing) -> xs0+             (Just ((xt,xb),xs), Just ((yt,yb),ys)) ->+                let (mt,~(b,dt)) = NonNeg.split xt yt+                in  uncurry (cons mt) $+                    if b && (dt/=zero || before xb yb)+                      then (xb, recourse xs $ cons dt yb ys)+                      else (yb, recourse ys $ cons dt xb xs)+   in  recourse + {- | 'insert' inserts an event into an event list at the given time. -} insert :: (NonNeg.C time, Ord body) =>    time -> body -> T time body -> T time body-insert t0 me0 =-   switchL-      (singleton t0 me0)-      (\ mev1@(t1, me1) mevs ->-          let mev0 = (t0, me0)-          in  if mev0 < mev1-                then uncurry cons mev0 $ cons   (t1-t0) me1 mevs-                else uncurry cons mev1 $ insert (t0-t1) me0 mevs)-+insert = insertBy (<)   insertBy :: (NonNeg.C time) =>@@ -402,12 +408,15 @@    time -> body -> T time body -> T time body insertBy before =    let recourse t0 me0 =+          (\ ~((t,me), rest) -> cons t me rest) .           switchL-             (singleton t0 me0)-             (\ mev1@(t1, me1) mevs ->-                 if beforeBy before (t0, me0) mev1-                   then cons t0 me0 $ cons     (t1-t0) me1 mevs-                   else cons t1 me1 $ recourse (t0-t1) me0 mevs)+             ((t0,me0), empty)+             (\(t1, me1) mevs ->+                let (mt,~(b,dt)) = NonNeg.split t0 t1+                in  mapFst ((,) mt) $+                    if b && (dt/=zero || before me0 me1)+                      then (me0, cons     dt me1 mevs)+                      else (me1, recourse dt me0 mevs))    in  recourse  @@ -416,7 +425,7 @@ You must make sure, that no event is moved before time zero. This works only for finite lists. -}-moveForward :: (NonNeg.C time) =>+moveForward :: (Ord time, Num time) =>    T time (time, body) -> T time body moveForward =    fromAbsoluteEventList .@@ -473,12 +482,12 @@ decreaseStart :: (NonNeg.C time) =>    time -> T time body -> T time body decreaseStart dif =-   mapTimeHead (subtract dif)+   mapTimeHead (-| dif)  delay :: (NonNeg.C time) =>    time -> T time body -> T time body delay dif =-   mapTimeHead (dif+)+   mapTimeHead (add dif)   @@ -506,7 +515,7 @@ discretize :: (NonNeg.C time, RealFrac time, NonNeg.C i, Integral i) =>    T time body -> T i body discretize =-   flip evalState 0.5 . mapTimeM floorDiff+   flip evalState 0.5 . mapTimeM Utility.floorDiff  resample :: (NonNeg.C time, RealFrac time, NonNeg.C i, Integral i) =>    time -> T time body -> T i body
src/Data/EventList/Relative/TimeMixed.hs view
@@ -94,22 +94,27 @@    time -> Disp.T time body ->    (Uniform.T body time, Disp.T time body) splitAtTimeAux t0 =+   mapFst Uniform.forceSecondHead .    Mixed.switchFirstL-      (Uniform.singleton 0, Disp.empty)+      (Mixed.consSecond NonNeg.zero Disp.empty, Disp.empty)       (\t1 xs ->-          if t0<=t1-            then (Uniform.singleton t0, Mixed.consFirst (t1-t0) xs)-            else-               Mixed.switchSecondL-                  (\b ys -> mapFst (Uniform.cons t1 b) (splitAtTimeAux (t0-t1) ys))-                  xs)+         let (mt,~(before,dt)) = NonNeg.split t0 t1+         in  mapFst (Mixed.consSecond mt) $+             if before+               then (Disp.empty, Mixed.consFirst dt xs)+               else+                  Mixed.switchSecondL+                     (\b ys ->+                        mapFst (Mixed.consFirst b) $+                        splitAtTimeAux dt ys)+                     xs)  splitAtTime :: (NonNeg.C time) =>    time -> TimeBodyList.T time body ->    (TimeTimeList.T time body, TimeBodyList.T time body)-splitAtTime t0 =+splitAtTime t =    mapPair (TimeTimePriv.Cons, TimeBodyPriv.Cons) .-   splitAtTimeAux t0 .+   splitAtTimeAux t .    TimeBodyPriv.decons  takeTime :: (NonNeg.C time) =>
src/Data/EventList/Relative/TimeTime.hs view
@@ -10,7 +10,7 @@ module Data.EventList.Relative.TimeTime    (T,     mapBody, mapTime,-    zipWithBody, zipWithTime,+    zipWithBody, zipWithTime, unzip,     concatMapMonoid,     traverse, traverse_, traverseBody, traverseTime,     mapM, mapM_, mapBodyM, mapTimeM,@@ -26,6 +26,7 @@     mapMaybe, catMaybes, catMaybesR,     append, concat, concatNaive, cycle, cycleNaive, reverse,     splitAtTime, takeTime, dropTime,+    forceTimeHead,     discretize, resample,     collectCoincident, flatten, mapCoincident,     normalize, isNormalized,@@ -47,9 +48,10 @@ import qualified Data.List as List import qualified Data.EventList.Utility as Utility -import Data.Monoid (Monoid, mconcat, mappend, )+import Data.Monoid (Monoid, mempty, mconcat, )  import qualified Numeric.NonNegative.Class as NonNeg+import Numeric.NonNegative.Class ((-|), zero, add, ) import Data.Tuple.HT (mapFst, mapSnd, mapPair, ) import Data.Maybe.HT (toMaybe, ) import Data.List.HT (isAscending, )@@ -61,7 +63,7 @@  import Prelude hiding    (null, foldr, foldl, map, filter, concat, cycle, reverse,-    sequence, sequence_, mapM, mapM_)+    sequence, sequence_, mapM, mapM_, unzip, )   @@ -79,8 +81,8 @@ getTimes :: T time body -> [time] getTimes = Uniform.getSeconds . decons -duration :: Num time => T time body -> time-duration = sum . getTimes+duration :: NonNeg.C time => T time body -> time+duration = NonNeg.sum . getTimes   @@ -132,6 +134,14 @@    (time0, [time0]) -> T time1 body -> T time2 body zipWithTime f = lift . Uniform.zipWithSecond f +unzip :: T time (body0, body1) -> (T time body0, T time body1)+unzip =+   foldr+      (\time ->+         mapPair (consTime time, consTime time))+      (\(body0, body1) ->+         mapPair (consBody body0, consBody body1))+      (mempty, mempty)   concatMapMonoid :: Monoid m =>@@ -210,51 +220,49 @@ mergeBy :: (NonNeg.C time) =>    (body -> body -> Bool) ->    T time body -> T time body -> T time body-mergeBy before xs0 ys0 =-   let (xt,xs) = viewTimeL xs0-       (yt,ys) = viewTimeL ys0-   in  case compare xt yt of-          LT -> mergeFirstBy before xs0 ys0-          GT -> mergeFirstBy before ys0 xs0-          EQ ->-             consTime xt $-             case (viewBodyL xs, viewBodyL ys) of-                (Nothing, _) -> ys-                (_, Nothing) -> xs-                (Just (b0,xs1), Just (b1,ys1)) ->-                   {- do not insert both b0 and b1 immediately,-                      because the later one of b0 and b1 may be pushed even further,-                      thus recourse with 'mergeBy' on xs or ys -}-                   if before b0 b1-                     then consBody b0 $ mergeBy before xs1 $ consTime 0 ys-                     else consBody b1 $ mergeBy before ys1 $ consTime 0 xs--{- | merge two time ordered lists provided that e0 is earlier than e1 -}-mergeFirstBy :: (NonNeg.C time) =>-   (body -> body -> Bool) ->-   T time body -> T time body -> T time body-mergeFirstBy before xs0 ys0 =-   let (xt,xs) = viewTimeL xs0-       (yt,ys) = viewTimeL ys0-   in  switchBodyL-          ys0-          (\ b xs1 ->-              consTime xt $ consBody b $ mergeBy before xs1 $ consTime (yt-xt) ys)-          xs+mergeBy before =+   let recourse xs0 ys0 =+          let (xt,xs) = viewTimeL xs0+              (yt,ys) = viewTimeL ys0+              (mt,~(bef,dt)) = NonNeg.split xt yt+          in  delay mt $+              if dt == zero+                then+                   case (viewBodyL xs, viewBodyL ys) of+                      (Nothing, _) -> consTime zero ys+                      (_, Nothing) -> consTime zero xs+                      (Just (b0,xs1), Just (b1,ys1)) ->+                         {-+                         do not insert both b0 and b1 immediately,+                         because the later one of b0 and b1 may be pushed even further,+                         thus recourse with 'mergeBy' on xs or ys+                         -}+                         if before b0 b1+                           then cons zero b0 $+                                recourse xs1 (consTime zero ys)+                           else cons zero b1 $+                                recourse (consTime zero xs) ys1+                else+                  if bef+                    then+                       let ys1 = consTime dt ys+                       in  flip (switchBodyL ys1) xs $ \ b xs1 ->+                              cons zero b $ recourse xs1 ys1+                    else+                       let xs1 = consTime dt xs+                       in  flip (switchBodyL xs1) ys $ \ b ys1 ->+                              cons zero b $ recourse xs1 ys1+   in  recourse   {- | Note that 'merge' 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}.+condition for some of the proofs used in Haskore/section equivalence. It is also necessary to assert a unique representation-of the performance independent of the structure of the 'Music.T note'.+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.-The strictness annotation is necessary for working with infinite lists.--Here are two other functions that are already known for non-padded time lists. -}- insert :: (NonNeg.C time, Ord body) =>    time -> body -> T time body -> T time body insert = insertBy (<)@@ -268,18 +276,19 @@    time -> body -> T time body -> T time body insertBy before t0 me0 =    let recurseTime t =-          switchTimeL (\ t1 xs ->-             if t<t1-               then cons t me0 (consTime (t1-t) xs)-               else recurseBody t1 t xs)-       recurseBody t1 t =-          switchBodyL-             (cons t me0 $ pause 0)-             (\ me1 xs ->-                 consTime t1 $-                    if t==t1 && before me0 me1-                      then consBody me0 (cons 0 me1 xs)-                      else consBody me1 (recurseTime (t-t1) xs))+          switchTimeL $ \ t1 xs0 ->+             let (mt,~(b,dt)) = NonNeg.split t1 t+             in  delay mt $+                 if not b+                   then cons zero me0 $ consTime dt xs0+                   else+                     switchBodyL+                        (cons dt me0 $ pause zero)+                        (\ me1 xs -> consTime zero $+                           if dt==zero && before me0 me1+                             then consBody me0 (cons zero me1 xs)+                             else consBody me1 (recurseTime dt xs))+                        xs0    in   recurseTime t0  @@ -297,7 +306,7 @@ You must make sure, that no event is moved before time zero. This works only for finite lists. -}-moveForward :: (NonNeg.C time) =>+moveForward :: (Ord time, Num time) =>    T time (time, body) -> T time body moveForward =    fromAbsoluteEventList .@@ -311,7 +320,7 @@    foldr       (\t -> cons t Nothing)       (\(t,b) -> insertBy (ltMaybe (\_ _ -> True)) t (Just b))-      (pause 0)+      (pause zero)  {- | Like 'moveForward' but restricts the look-ahead time.@@ -332,7 +341,7 @@ moveForwardRestricted maxTime =    decreaseStart maxTime .    moveBackward .-   mapBody (mapFst (maxTime-)) .+   mapBody (mapFst (maxTime-|)) .    pad maxTime {-    moveForwardRestrictedBy@@ -357,7 +366,7 @@    catMaybes .    foldr       (\t -> cons t Nothing)-      (\(t,b) -> insertBy (ltMaybe cmp) (maxTime-t) (Just b))+      (\(t,b) -> insertBy (ltMaybe cmp) (maxTime-|t) (Just b))       (pause maxTime)  -- | currently only for testing@@ -368,11 +377,11 @@    decreaseStart maxTime .    foldr       delay-      (\(t,b) -> insertBy cmp (maxTime-t) b)+      (\(t,b) -> insertBy cmp (maxTime-|t) b)       (pause maxTime)  -- | currently only for testing-moveForwardRestrictedByQueue :: (NonNeg.C time) =>+moveForwardRestrictedByQueue :: (NonNeg.C time, Num time) =>    (body -> body -> Bool) ->    time -> T time (time, body) -> T time body moveForwardRestrictedByQueue cmp maxTime xs =@@ -399,7 +408,7 @@ -} arrange :: (Ord body, NonNeg.C time) =>    T time (T time body) -> T time body-arrange = arrangeBy (\_ _ -> False)+arrange = arrangeBy (\_ _ -> True)  arrangeBy :: (NonNeg.C time) =>    (body -> body -> Bool) ->@@ -409,16 +418,9 @@    foldr       (\t -> cons t Nothing)       (\xs -> mergeBy (ltMaybe cmp) (mapBody Just xs))-      (pause 0)+      (pause zero)  -{--not lazy enough for @append (2 /. 'a' ./ 4 /. 'b' ./ 2 /. undefined) undefined@--}-append :: (NonNeg.C time) =>-   T time body -> T time body -> T time body-append = mappend- concat :: (NonNeg.C time) =>    [T time body] -> T time body concat = mconcat@@ -433,7 +435,7 @@ -} concatNaive :: (NonNeg.C time) =>    [T time body] -> T time body-concatNaive = List.foldr append (pause 0)+concatNaive = List.foldr append (pause zero)   {- |@@ -446,7 +448,7 @@    (\t0 xs ->        consTime t0 $        BodyTimePriv.cycle $-       BodyTimePriv.mapTimeLast (+t0) xs)+       BodyTimePriv.mapTimeLast (add t0) xs)   cycleNaive :: (NonNeg.C time) =>@@ -472,13 +474,19 @@ splitAtTime t0 =    switchTimeL    (\t1 xs ->-        if t0<=t1-          then (pause t0, consTime (t1-t0) xs)-          else-             switchBodyL-                (pause t1, pause 0)-                (\ b -> mapFst (cons t1 b) . splitAtTime (t0-t1))-                xs)+      let (mt,~(bef,dt)) = NonNeg.split t0 t1+      in  {-+          The handling of the second pair member looks a bit cumbersome,+          but it is necessary to prepend the time once+          in order to prevent a memory leak.+          -}+          mapPair (consTime mt, forceTimeHead) $+          if bef+            then (mempty, consTime dt xs)+            else switchBodyL+                    (mempty, pause zero)+                    (\ b -> mapFst (consBody b) . splitAtTime dt)+                    xs)  takeTime :: (NonNeg.C time) =>    time -> T time body -> T time body@@ -486,13 +494,42 @@  dropTime :: (NonNeg.C time) =>    time -> T time body -> T time body-dropTime t = snd . splitAtTime t+-- dropTime t = snd . splitAtTime t+dropTime t0 =+   switchTimeL+   (\t1 xs ->+      let (bef,dt) = snd $ NonNeg.split t0 t1+      in  forceTimeHead $+          if bef+            then consTime dt xs+            else switchBodyL+                    (pause zero)+                    (\ _b -> dropTime dt)+                    xs) +{-+Surprisingly this has a space leak,+see test dropTimeLazyInfinite. +dropTime :: (NonNeg.C time) =>+   time -> T time body -> T time body+dropTime t0 =+   switchTimeL+   (\t1 xs ->+      let (bef,dt) = snd $ NonNeg.split t0 t1+      in  if bef+            then consTime dt xs+            else switchBodyL+                    (pause zero)+                    (\ _b -> dropTime dt)+                    xs)+-}++ decreaseStart :: (NonNeg.C time) =>    time -> T time body -> T time body decreaseStart dif =-   mapTimeHead (subtract dif)+   mapTimeHead (-| dif)   collectCoincident :: (NonNeg.C time) => T time body -> T time [body]@@ -514,12 +551,12 @@ from the beginning to the end. -} -filter :: (Num time) =>+filter :: (NonNeg.C time) =>    (body -> Bool) ->    T time body -> T time body filter p = mapMaybe (\b -> toMaybe (p b) b) -mapMaybe :: (Num time) =>+mapMaybe :: (NonNeg.C time) =>    (body0 -> Maybe body1) ->    T time body0 -> T time body1 mapMaybe f = catMaybes . mapBody f@@ -528,48 +565,50 @@ Adds times in a left-associative fashion. Use this if the time is a strict data type. -}-catMaybes :: (Num time) =>+catMaybes :: (NonNeg.C time) =>    T time (Maybe body) -> T time body-catMaybes = mapTime sum . lift Uniform.catMaybesFirst+catMaybes = mapTime NonNeg.sum . lift Uniform.catMaybesFirst  {- | Adds times in a right-associative fashion. Use this if the time is a data type like lazy Peano numbers or "Numeric.NonNegative.Chunky". -}-catMaybesR :: (Num time) =>+catMaybesR :: (NonNeg.C time) =>    T time (Maybe body) -> T time body catMaybesR =    foldr-      (mapTimeHead . (+))-      (maybe id (cons 0))-      (pause 0)+      (mapTimeHead . add)+      (maybe id (cons zero))+      (pause zero) -partition :: (Num time) =>+partition :: (NonNeg.C time) =>    (body -> Bool) ->    T time body -> (T time body, T time body) partition p =-   mapPair (mapTime sum, mapTime sum) .+   mapPair (mapTime NonNeg.sum, mapTime NonNeg.sum) .    mapPair (Cons, Cons) .    Uniform.partitionFirst p .    decons -partitionMaybe :: (Num time) =>+partitionMaybe :: (NonNeg.C time) =>    (body0 -> Maybe body1) -> T time body0 ->    (T time body1, T time body0) partitionMaybe f =-   mapPair (mapTime sum . Cons, mapTime sum . Cons) .+   mapPair (mapTime NonNeg.sum . Cons, mapTime NonNeg.sum . Cons) .    Uniform.partitionMaybeFirst f .    decons  {- | Cf. 'catMaybesR' -}-partitionMaybeR :: (Num time) =>+partitionMaybeR :: (NonNeg.C time) =>    (body0 -> Maybe body1) -> T time body0 ->    (T time body1, T time body0) partitionMaybeR f =-   mapPair (mapTime (List.foldr (+) 0), mapTime (List.foldr (+) 0)) .+   mapPair+      (mapTime (List.foldr add zero),+       mapTime (List.foldr add zero)) .    mapPair (Cons, Cons) .    Uniform.partitionMaybeFirst f .    decons@@ -578,13 +617,10 @@ Since we need it later for MIDI generation, we will also define a slicing into equivalence classes of events. -}-slice :: (Eq a, Num time) =>+slice :: (Eq a, NonNeg.C time) =>    (body -> a) -> T time body -> [(a, T time body)] slice = Utility.slice (fmap fst . viewBodyL . snd . viewTimeL) partition --foldr :: (time -> a -> b) -> (body -> b -> a) -> a -> T time body -> b-foldr f g x = Uniform.foldr g f x . decons  foldl :: (a -> time -> b) -> (b -> body -> a) -> a -> T time body -> b foldl f g x = Uniform.foldl g f x . decons
src/Data/EventList/Relative/TimeTimePrivate.hs view
@@ -20,6 +20,7 @@ import qualified Data.AlternatingList.List.Mixed as Mixed  import qualified Numeric.NonNegative.Class as NonNeg+import Numeric.NonNegative.Class (zero, add, )  import Data.Tuple.HT (mapFst, mapSnd, ) @@ -32,6 +33,7 @@  import Test.QuickCheck (Arbitrary(arbitrary)) +import Prelude hiding (foldr, )   newtype T time body = Cons {decons :: Uniform.T body time}@@ -47,15 +49,43 @@   instance (NonNeg.C time) => Monoid (T time body) where-   mempty = Cons (Uniform.singleton 0)-   mappend =-      switchTimeR-      (\ xs t -> lift (Mixed.appendDisparateUniform $~* xs) . delay t)+   mempty = Cons (Uniform.singleton zero)+   mappend = append    mconcat =-      flatten . consTime 0 .+      flatten . consTime zero .       mconcat .       map (consBody [] . fmap (:[])) +append, appendAlt, appendSwitch ::+   (NonNeg.C time) =>+   T time body -> T time body -> T time body+append xs ys =+   forceTimeHead $+   foldr+      delay+      (\b ->+         consTime NonNeg.zero .+         consBody b)+      ys xs++appendAlt xs ys =+   foldr+      (\t ->+         delay t .+         either id (consTime NonNeg.zero))+      (\b -> Right . consBody b)+      (Left ys) xs++{-+not lazy enough for @append (2 /. 'a' ./ 4 /. 'b' ./ 2 /. undefined) undefined@+-}+appendSwitch =+   switchTimeR+      (\ xs t ->+         lift (Mixed.appendDisparateUniform $~* xs) .+         delay t)++ instance Functor (T time) where    fmap f (Cons x) = Cons (Uniform.mapFirst f x) @@ -154,6 +184,8 @@    switchTimeL (\time -> consTime time . f) {- This causes a memory leak when used with chunky time values.+I have found this problem in synthesizer-alsa:EventList.MIDI.matchNote,+but I could not reliably reproduce that in smaller setups.  mapTimeTail =    lift . Mixed.mapSecondTail . BodyTimePriv.unlift@@ -176,19 +208,27 @@ mapTimeInit = lift . Mixed.mapSecondInit . TimeBodyPriv.unlift  +foldr :: (time -> a -> b) -> (body -> b -> a) -> a -> T time body -> b+foldr f g x = Uniform.foldr g f x . decons++forceTimeHead :: (NonNeg.C time) =>+   T time body -> T time body+forceTimeHead =+   mapTimeHead id+ delay :: (NonNeg.C time) =>    time -> T time body -> T time body delay dif =-   mapTimeHead (dif+)+   mapTimeHead (add dif) -flatten :: (Num time) => T time [body] -> T time body+flatten :: (NonNeg.C time) => T time [body] -> T time body flatten =    Cons .    Uniform.foldr-      (Mixed.appendUniformUniform . Uniform.fromSecondList 0)+      (Mixed.appendUniformUniform . Uniform.fromSecondList zero)       Mixed.consSecond    -- consTime       Disp.empty . --      (\(b:bs) xs -> consBody b (List.foldr (cons 0) xs bs)) empty .-   Uniform.mapSecond sum .+   Uniform.mapSecond NonNeg.sum .    Uniform.filterFirst (not . null) .    decons
src/Data/EventList/Utility.hs view
@@ -37,7 +37,7 @@  beforeBy :: (Ord time) =>    (body -> body -> Bool) ->-   (time, body) -> (time, body) ->  Bool+   (time, body) -> (time, body) -> Bool beforeBy before (t0, me0) (t1, me1) =    case compare t0 t1 of       LT -> True
src/Test/Data/EventList/Absolute/BodyEnd.hs view
@@ -38,19 +38,22 @@  infixl 4 ==~ -(==~) :: (Eq body, Num time) =>+(==~) :: (Eq body, NonNeg.C time, Num time) =>    AbsBody.T time body -> RelBody.T time body -> Bool (==~) xs ys =    xs == RelBody.toAbsoluteEventList 0 ys   -duration :: Num time => RelBody.T time body -> Bool+duration ::+   (NonNeg.C time, Num time) =>+   RelBody.T time body -> Bool duration xs =    AbsBody.duration $~ xs == RelBody.duration xs  -mapBody :: (Eq body1, Num time) =>+mapBody ::+   (Eq body1, NonNeg.C time, Num time) =>    (body0 -> body1) -> RelBody.T time body0 -> Bool mapBody f xs =    AbsBody.mapBody f $~ xs ==~ RelBody.mapBody f xs@@ -58,7 +61,7 @@   mapBodyM ::-   (Monad m, Eq body1, NonNeg.C time) =>+   (Monad m, Eq body1, NonNeg.C time, Num time) =>    (m (AbsBody.T time body1) -> AbsBody.T time body1) ->    (body0 -> m body1) -> RelBody.T time body0 -> Bool mapBodyM run f xs =@@ -66,7 +69,7 @@    run (liftM (RelBody.toAbsoluteEventList 0) (RelBody.mapBodyM f xs))  mapBodyMRandom ::-   (NonNeg.C time, Random body, Eq body) =>+   (NonNeg.C time, Num time, Random body, Eq body) =>    Int -> RelBody.T time (body, body) -> Bool mapBodyMRandom seed =    mapBodyM @@ -74,7 +77,7 @@       (state . randomR)  -filter :: (Eq body, Num time) =>+filter :: (Eq body, NonNeg.C time, Num time) =>    (body -> Bool) -> RelBody.T time body -> Bool filter p xs =    AbsBody.filter p $~ xs ==~ RelBody.filter p xs@@ -86,7 +89,7 @@ mapMaybe f = catMaybes . mapBody f -} -catMaybes :: (Eq body, Num time) =>+catMaybes :: (Eq body, NonNeg.C time, Num time) =>    RelBody.T time (Maybe body) -> Bool catMaybes xs =    AbsBody.catMaybes $~ xs ==~ RelBody.catMaybes xs@@ -94,7 +97,7 @@ {- Could be implemented more easily in terms of Uniform.partition -}-partition :: (Eq body, Num time) =>+partition :: (Eq body, NonNeg.C time, Num time) =>    (body -> Bool) -> RelBody.T time body -> Bool partition p xs =    AbsBody.partition p $~ xs ==@@ -106,32 +109,33 @@ Since we need it later for MIDI generation, we will also define a slicing into equivalence classes of events. -}-slice :: (Eq a, Eq body, Num time) =>+slice :: (Eq a, Eq body, NonNeg.C time, Num time) =>    (body -> a) -> RelBody.T time body -> Bool slice f xs =    AbsBody.slice f $~ xs ==    map (mapSnd (RelBody.toAbsoluteEventList 0)) (RelBody.slice f xs)  -collectCoincident :: (NonNeg.C time, Eq body) =>+collectCoincident :: (Eq body, NonNeg.C time, Num time) =>    RelBody.T time body -> Bool collectCoincident xs =    AbsBody.collectCoincident $~ xs ==~    RelBody.collectCoincident xs -collectCoincidentFoldr :: (NonNeg.C time, Eq body) =>+collectCoincidentFoldr :: (Eq body, NonNeg.C time, Num time) =>    RelBody.T time body -> Bool collectCoincidentFoldr xs =    AbsBody.collectCoincident $~ xs ==    AbsBody.collectCoincidentFoldr $~ xs -collectCoincidentNonLazy :: (NonNeg.C time, Eq body) =>+collectCoincidentNonLazy :: (Eq body, NonNeg.C time, Num time) =>    RelBody.T time body -> Bool collectCoincidentNonLazy xs =    AbsBody.collectCoincident $~ xs ==    AbsBody.collectCoincidentNonLazy $~ xs -collectCoincidentInfinite :: (NonNeg.C time, Eq body) =>+collectCoincidentInfinite ::+   (Eq body, NonNeg.C time, Num time) =>    NonEmptyList time body -> Bool collectCoincidentInfinite =    checkInfinite .@@ -139,38 +143,38 @@    makeUncollapsedInfiniteEventList  -flatten :: (NonNeg.C time, Eq body) =>+flatten :: (Eq body, NonNeg.C time, Num time) =>    RelBody.T time [body] -> Bool flatten xs =    AbsBody.flatten $~ xs  ==~  RelBody.flatten xs  -normalize :: (NonNeg.C time, Ord body) =>+normalize :: (Ord body, NonNeg.C time, Num time) =>    RelBody.T time body -> Bool normalize xs =    AbsBody.normalize $~ xs  ==~  RelBody.normalize xs  -merge :: (NonNeg.C time, Ord body) =>+merge :: (Ord body, NonNeg.C time, Num time) =>    RelBody.T time body -> RelBody.T time body -> Bool merge xs ys =    AbsBody.merge $~ xs $~ ys  ==~  RelBody.merge xs ys  -insert :: (NonNeg.C time, Ord body) =>+insert :: (Ord body, NonNeg.C time, Num time) =>    time -> body -> RelBody.T time body -> Bool insert t b xs =    AbsBody.insert t b $~ xs  ==~  RelBody.insert t b xs   -append :: (NonNeg.C time, Eq body) =>+append :: (Eq body, NonNeg.C time, Num time) =>    RelBody.T time body -> RelBody.T time body -> Bool append xs ys =    AbsBody.append $~ xs $~ ys  ==~    RelBody.append xs ys -concat :: (NonNeg.C time, Eq body) =>+concat :: (Eq body, NonNeg.C time, Num time) =>    [RelBody.T time body] -> Bool concat xs =    AbsBody.concat (map (RelBody.toAbsoluteEventList 0) xs)  ==~@@ -184,7 +188,7 @@ -}  -decreaseStart :: (NonNeg.C time, Eq body) =>+decreaseStart :: (Eq body, NonNeg.C time, Num time) =>    time -> time -> RelBody.T time body -> Bool decreaseStart dif0 dif1 xs0 =    let difA = min dif0 dif1@@ -194,7 +198,7 @@        RelBody.decreaseStart difA xs  -delay :: (NonNeg.C time, Eq body) =>+delay :: (Eq body, NonNeg.C time, Num time) =>    time -> RelBody.T time body -> Bool delay dif xs =    AbsBody.delay dif $~ xs  ==~@@ -243,13 +247,15 @@  type NonEmptyList time body = ((time, body), RelBody.T time body) -makeUncollapsedInfiniteEventList :: (NonNeg.C time) =>+makeUncollapsedInfiniteEventList ::+   (NonNeg.C time, Num time) =>    NonEmptyList time body -> AbsBody.T time body makeUncollapsedInfiniteEventList =    makeInfiniteEventList .    mapFst (mapFst (1+)) -makeInfiniteEventList :: (NonNeg.C time) =>+makeInfiniteEventList ::+   (NonNeg.C time, Num time) =>    NonEmptyList time body -> AbsBody.T time body makeInfiniteEventList =    RelBody.toAbsoluteEventList 0 . RelBody.cycle . makeNonEmptyEventList
src/Test/Data/EventList/Absolute/TimeEnd.hs view
@@ -45,12 +45,14 @@   -duration :: Num time => RelTime.T time body -> Bool+duration ::+   (NonNeg.C time, Num time) =>+   RelTime.T time body -> Bool duration xs =    AbsTime.duration $~ xs == RelTime.duration xs  -mapBody :: (Eq body1, Num time) =>+mapBody :: (Eq body1, NonNeg.C time, Num time) =>    (body0 -> body1) -> RelTime.T time body0 -> Bool mapBody f xs =    AbsTime.mapBody f $~ xs ==~ RelTime.mapBody f xs@@ -58,7 +60,7 @@   mapBodyM ::-   (Monad m, Eq body1, NonNeg.C time) =>+   (Monad m, Eq body1, NonNeg.C time, Num time) =>    (m (AbsTime.T time body1) -> AbsTime.T time body1) ->    (body0 -> m body1) -> RelTime.T time body0 -> Bool mapBodyM run f xs =@@ -66,7 +68,7 @@    run (liftM (RelTime.toAbsoluteEventList 0) (RelTime.mapBodyM f xs))  mapBodyMRandom ::-   (NonNeg.C time, Random body, Eq body) =>+   (NonNeg.C time, Num time, Random body, Eq body) =>    Int -> RelTime.T time (body, body) -> Bool mapBodyMRandom seed =    mapBodyM @@ -74,19 +76,19 @@       (state . randomR)  -filter :: (Eq body, Num time) =>+filter :: (Eq body, NonNeg.C time, Num time) =>    (body -> Bool) -> RelTime.T time body -> Bool filter p xs =    AbsTime.filter p $~ xs ==~ RelTime.filter p xs  {--mapMaybe :: (Num time) =>+mapMaybe :: (NonNeg.C time, Num time) =>    (body0 -> Maybe body1) ->    RelTime.T time body0 -> RelTime.T time body1 mapMaybe f = catMaybes . mapBody f -} -catMaybes :: (Eq body, Num time) =>+catMaybes :: (Eq body, NonNeg.C time, Num time) =>    RelTime.T time (Maybe body) -> Bool catMaybes xs =    AbsTime.catMaybes $~ xs ==~ RelTime.catMaybes xs@@ -94,7 +96,7 @@ {- Could be implemented more easily in terms of Uniform.partition -}-partition :: (Eq body, Num time) =>+partition :: (Eq body, NonNeg.C time, Num time) =>    (body -> Bool) -> RelTime.T time body -> Bool partition p xs =    AbsTime.partition p $~ xs ==@@ -106,20 +108,20 @@ Since we need it later for MIDI generation, we will also define a slicing into equivalence classes of events. -}-slice :: (Eq a, Eq body, Num time) =>+slice :: (Eq a, Eq body, NonNeg.C time, Num time) =>    (body -> a) -> RelTime.T time body -> Bool slice f xs =    AbsTime.slice f $~ xs ==    map (mapSnd (RelTime.toAbsoluteEventList 0)) (RelTime.slice f xs)  -collectCoincident :: (NonNeg.C time, Eq body) =>+collectCoincident :: (NonNeg.C time, Num time, Eq body) =>    RelTime.T time body -> Bool collectCoincident xs =    AbsTime.collectCoincident $~ xs ==~    RelTime.collectCoincident xs -collectCoincidentInfinite :: (NonNeg.C time, Eq body) =>+collectCoincidentInfinite :: (NonNeg.C time, Num time, Eq body) =>    NonEmptyList time body -> Bool collectCoincidentInfinite =    checkInfinite .@@ -127,38 +129,48 @@    makeUncollapsedInfiniteEventList  -flatten :: (NonNeg.C time, Eq body) =>+flatten :: (NonNeg.C time, Num time, Eq body) =>    RelTime.T time [body] -> Bool flatten xs =    AbsTime.flatten $~ xs  ==~  RelTime.flatten xs  -normalize :: (NonNeg.C time, Ord body) =>+normalize :: (NonNeg.C time, Num time, Ord body) =>    RelTime.T time body -> Bool normalize xs =    AbsTime.normalize $~ xs  ==~  RelTime.normalize xs  -merge :: (NonNeg.C time, Ord body) =>+{-+test fails++1 /. '\DEL' ./ 0 /. '"' ./ 1 /. '}' ./ 0 /. empty+0 /. '\DEL' ./ 1 /. '}' ./ 0 /. '\DEL' ./ 1 /. empty+++4 /. '|' ./ 0 /. '!' ./ 3 /. '"' ./ 1 /. '!' ./ 3 /. empty+1 /. '$' ./ 2 /. '~' ./ 1 /. '|' ./ 1 /. '|' ./ 1 /. empty+-}+merge :: (NonNeg.C time, Num time, Ord body) =>    RelTime.T time body -> RelTime.T time body -> Bool merge xs ys =    AbsTime.merge $~ xs $~ ys  ==~  RelTime.merge xs ys  -insert :: (NonNeg.C time, Ord body) =>+insert :: (NonNeg.C time, Num time, Ord body) =>    time -> body -> RelTime.T time body -> Bool insert t b xs =    AbsTime.insert t b $~ xs  ==~  RelTime.insert t b xs   -append :: (NonNeg.C time, Eq body) =>+append :: (NonNeg.C time, Num time, Eq body) =>    RelTime.T time body -> RelTime.T time body -> Bool append xs ys =    AbsTime.append $~ xs $~ ys  ==~    RelTime.append xs ys -concat :: (NonNeg.C time, Eq body) =>+concat :: (NonNeg.C time, Num time, Eq body) =>    [RelTime.T time body] -> Bool concat xs =    AbsTime.concat (map (RelTime.toAbsoluteEventList 0) xs)  ==~@@ -172,7 +184,7 @@ -}  -decreaseStart :: (NonNeg.C time, Eq body) =>+decreaseStart :: (NonNeg.C time, Num time, Eq body) =>    time -> time -> RelTime.T time body -> Bool decreaseStart dif0 dif1 xs0 =    let difA = min dif0 dif1@@ -182,7 +194,7 @@        RelTime.decreaseStart difA xs  -delay :: (NonNeg.C time, Eq body) =>+delay :: (NonNeg.C time, Num time, Eq body) =>    time -> RelTime.T time body -> Bool delay dif xs =    AbsTime.delay dif $~ xs  ==~@@ -219,18 +231,18 @@  type NonEmptyList time body = ((time, body), RelTime.T time body) -makeUncollapsedInfiniteEventList :: (NonNeg.C time) =>+makeUncollapsedInfiniteEventList :: (NonNeg.C time, Num time) =>    NonEmptyList time body -> AbsTime.T time body makeUncollapsedInfiniteEventList =    makeInfiniteEventList .    mapFst (mapFst (1+)) -makeInfiniteEventList :: (NonNeg.C time) =>+makeInfiniteEventList :: (NonNeg.C time, Num time) =>    NonEmptyList time body -> AbsTime.T time body makeInfiniteEventList =    RelTime.toAbsoluteEventList 0 . RelTime.cycle . makeNonEmptyEventList -makeNonEmptyEventList :: (NonNeg.C time) =>+makeNonEmptyEventList :: (NonNeg.C time, Num time) =>    NonEmptyList time body -> RelTime.T time body makeNonEmptyEventList (p, evs) =    uncurry RelTime.cons p evs
src/Test/Data/EventList/Relative/BodyEnd.hs view
@@ -21,8 +21,9 @@  import Data.EventList.Relative.MixedBody ((/.), (./), empty) +import qualified Numeric.NonNegative.Chunky as NonNegChunky import qualified Numeric.NonNegative.Class as NonNeg-import Numeric.NonNegative.Class ((-|))+import Numeric.NonNegative.Class ((-|), zero, add, ) import Data.EventList.Relative.TimeBody (isNormalized)  import Data.Tuple.HT (mapFst, mapPair, )@@ -208,7 +209,7 @@ delayAdditive :: (NonNeg.C time, Eq body) =>    time -> time -> TimeBodyList.T time body -> Bool delayAdditive dif0 dif1 xs =-   TimeBodyList.delay (dif0+dif1) xs ==+   TimeBodyList.delay (add dif0 dif1) xs ==    TimeBodyList.delay dif0 (TimeBodyList.delay dif1 xs)  delayAppendPause :: (NonNeg.C time, Eq body) =>@@ -234,9 +235,9 @@ takeTimeEndPause :: (NonNeg.C time, Ord body) =>    time -> TimeBodyList.T time body -> Bool takeTimeEndPause t xs =-   t == 0 ||+   t == zero ||    t >= TimeBodyList.duration xs ||-   0 <  snd (TimeMixedList.viewTimeR (TimeMixedList.takeTime t xs))+   zero <  snd (TimeMixedList.viewTimeR (TimeMixedList.takeTime t xs))  takeTimeAppendFirst :: (NonNeg.C time, Eq body) =>    time -> TimeBodyList.T time body -> TimeBodyList.T time body -> Bool@@ -246,12 +247,12 @@       (TimeMixedList.takeTime t xs)       (TimeMixedList.takeTime (t -| TimeBodyList.duration xs) ys) -takeTimeAppendSecond :: (NonNeg.C time, Eq body) =>+takeTimeAppendSecond :: (NonNeg.C time, Num time, Eq body) =>    time -> TimeBodyList.T time body -> TimeBodyList.T time body -> Bool takeTimeAppendSecond t xs ys0 =    -- the second list must not start with a zero pause    let ys = TimeBodyList.delay 1 ys0-       t1 = t+1+       t1 = add t 1    in  TimeMixedList.takeTime (TimeBodyList.duration xs + t1) (TimeBodyList.append xs ys) ==        TimeMixedList.prependBodyEnd xs (TimeMixedList.takeTime t1 ys) @@ -265,26 +266,43 @@ dropTimeNormalize t =    isNormalized . TimeMixedList.dropTime t . TimeBodyList.normalize -takeTimeInfinite :: (NonNeg.C time, Ord body) =>+takeTimeInfinite :: (NonNeg.C time, Num time, Ord body) =>    time -> NonEmptyList time body -> Bool takeTimeInfinite t =    (t == ) . TimeTimeList.duration .    TimeMixedList.takeTime t . makeUncollapsedInfiniteEventList -dropTimeInfinite :: (NonNeg.C time, Ord body) =>+dropTimeInfinite :: (NonNeg.C time, Num time, Ord body) =>    time -> NonEmptyList time body -> Bool dropTimeInfinite t =    checkInfinite . TimeMixedList.dropTime t . makeUncollapsedInfiniteEventList +_splitAtTimeLazyInfinite ::+   (NonNeg.C time, Num time, Ord body, Show time, Show body) =>+   BodyBodyList.T (NonNegChunky.T time) body -> Bool+_splitAtTimeLazyInfinite =+   not . null . show . snd .+   TimeMixedList.splitAtTime 1000000 .+   MixedBodyList.consTime+      (NonNegChunky.fromChunks $ iterate (2-) 1) +_dropTimeLazyInfinite ::+   (NonNeg.C time, Num time, Ord body, Show time, Show body) =>+   BodyBodyList.T (NonNegChunky.T time) body -> Bool+_dropTimeLazyInfinite =+   not . null . show .+   TimeMixedList.dropTime 1000000 .+   MixedBodyList.consTime+      (NonNegChunky.fromChunks $ iterate (2-) 1)  + durationPause :: (NonNeg.C time) =>    time -> Bool durationPause t =    t == TimeBodyList.duration (TimeBodyList.singleton t (error "durationPause: no need to access body")) -durationAppend :: (NonNeg.C time) =>+durationAppend :: (NonNeg.C time, Num time) =>    TimeBodyList.T time body -> TimeBodyList.T time body -> Bool durationAppend xs ys =    TimeBodyList.duration (TimeBodyList.append xs ys)  ==@@ -323,20 +341,20 @@    in  equalPrefix 100 xs (TimeBodyList.cycle xs)  -filterSatisfy :: (Num time) =>+filterSatisfy :: (NonNeg.C time) =>    (body -> Bool) ->    TimeBodyList.T time body -> Bool filterSatisfy p =    all p . TimeBodyList.getBodies . TimeBodyList.filter p -filterProjection :: (Num time, Eq body) =>+filterProjection :: (NonNeg.C time, Eq body) =>    (body -> Bool) ->    TimeBodyList.T time body -> Bool filterProjection p xs =    TimeBodyList.filter p xs ==    TimeBodyList.filter p (TimeBodyList.filter p xs) -filterCommutative :: (Num time, Eq body) =>+filterCommutative :: (NonNeg.C time, Eq body) =>    (body -> Bool) ->    (body -> Bool) ->    TimeBodyList.T time body -> Bool@@ -344,7 +362,7 @@    TimeBodyList.filter p (TimeBodyList.filter q xs) ==    TimeBodyList.filter q (TimeBodyList.filter p xs) -filterComposition :: (Num time, Eq body) =>+filterComposition :: (NonNeg.C time, Eq body) =>    (body -> Bool) ->    (body -> Bool) ->    TimeBodyList.T time body -> Bool@@ -503,6 +521,12 @@    TimeBodyList.insert time0 body0 (TimeBodyList.insert time1 body1 evs)  ==    TimeBodyList.insert time1 body1 (TimeBodyList.insert time0 body0 evs) +{-+Relative.BodyEnd.insert merge: Falsifiable, after 12 tests:+2+'}'+1 /. '%' ./ 1 /. '}' ./ 0 /. ' ' ./ 5 /. 'z' ./ 5 /. '\'' ./ 2 /. '\DEL' ./ 2 /. 'x' ./ 3 /. '\DEL' ./ empty+-} insertMerge :: (NonNeg.C time, Ord body) =>    time -> body -> TimeBodyList.T time body -> Bool insertMerge time body evs =@@ -523,7 +547,7 @@    ==       let (prefix,suffix) = TimeMixedList.splitAtTime time evs       in  TimeBodyList.normalize (TimeMixedList.appendBodyEnd prefix-             (MixedBodyList.consTime 0 (MixedBodyList.consBody body suffix)))+             (MixedBodyList.consTime zero (MixedBodyList.consBody body suffix)))  insertInfinite :: (NonNeg.C time, Ord body) =>    time -> body -> NonEmptyList time body -> Bool@@ -532,21 +556,21 @@   -moveForwardIdentity :: (NonNeg.C time, Ord body) =>+moveForwardIdentity :: (NonNeg.C time, Num time, Ord body) =>    TimeBodyList.T time body -> Bool moveForwardIdentity evs =    evs ==-   TimeBodyList.moveForward (TimeBodyList.mapBody ((,) 0) evs)+   TimeBodyList.moveForward (TimeBodyList.mapBody ((,) zero) evs) -moveForwardAdditive :: (NonNeg.C time, Ord body) =>+moveForwardAdditive :: (NonNeg.C time, Num time, Ord body) =>    TimeBodyList.T time ((time,time),body) -> Bool moveForwardAdditive evs =    TimeBodyList.normalize (moveForwardLimited (moveForwardLimited       (TimeBodyList.mapBody (\((t0,t1),b) -> (t0,(t1,b))) evs))) ==    TimeBodyList.normalize (moveForwardLimited-      (TimeBodyList.mapBody (mapFst (uncurry (+))) evs))+      (TimeBodyList.mapBody (mapFst (uncurry add)) evs)) -moveForwardCommutative :: (NonNeg.C time, Ord body) =>+moveForwardCommutative :: (NonNeg.C time, Num time, Ord body) =>    TimeBodyList.T time ((time,time),body) -> Bool moveForwardCommutative evs =    TimeBodyList.normalize (moveForwardLimited (moveForwardLimited@@ -575,16 +599,16 @@ -}  -moveForwardLimited :: (NonNeg.C time) =>+moveForwardLimited :: (NonNeg.C time, Num time) =>    TimeBodyList.T time (time,body) -> TimeBodyList.T time body moveForwardLimited = TimeBodyList.moveForward . restrictMoveTimes  restrictMoveTimes :: (NonNeg.C time) =>    TimeBodyList.T time (time,body) -> TimeBodyList.T time (time,body) restrictMoveTimes =-   flip evalState 0 .+   flip evalState zero .    TimeBodyList.mapM-      (\t -> modify (t+) >> return t)+      (\t -> modify (add t) >> return t)       (\(t,b) -> gets (\tm -> (min t tm, b)))  @@ -619,14 +643,14 @@    TimeBodyList.T time body -> Bool collectCoincidentGaps xs =    let times = TimeBodyList.getTimes (TimeBodyList.collectCoincident xs)-   in  null times || all (0<) (tail times)+   in  null times || all (zero<) (tail times)  collectCoincidentNonEmpty :: (NonNeg.C time, Eq body) =>    TimeBodyList.T time body -> Bool collectCoincidentNonEmpty =    all (not . null) . TimeBodyList.getBodies . TimeBodyList.collectCoincident -collectCoincidentInfinite :: (NonNeg.C time, Eq body) =>+collectCoincidentInfinite :: (NonNeg.C time, Num time, Eq body) =>    NonEmptyList time body -> Bool collectCoincidentInfinite =    checkInfinite .@@ -720,7 +744,7 @@    EventList.insert time body (fst evs)  ==  fst (insert time body evs) -} -appendSingle :: -- (Num time, Ord time, Ord body) =>+appendSingle :: -- (NonNeg.C time, Ord time, Ord body) =>    body -> TimeBodyList.T time body -> EventList.T time body appendSingle body xs =    Disp.foldr EventList.consTime EventList.consBody EventList.empty $@@ -742,7 +766,7 @@ discretize :: (RealFrac time, Integral i) =>    TimeBodyList.T time body -> TimeBodyList.T i body discretize es =-   evalState (Uniform.mapSecondM roundDiff es) 0+   evalState (Uniform.mapSecondM roundDiff es) zero  resample :: (RealFrac time, Integral i) =>    time -> TimeBodyList.T time body -> TimeBodyList.T i body@@ -755,7 +779,7 @@ toAbsoluteEventList start xs =    let ts = Uniform.getSeconds xs        bs = Uniform.getFirsts  xs-       ats = List.scanl (+) start ts+       ats = List.scanl add start ts    in  maybe           (error "padded list always contains one time value")           (\ ~(ats0,lt) -> (zip ats0 bs, lt))@@ -767,11 +791,12 @@  type NonEmptyList time body = (time, body, TimeBodyList.T time body) -makeUncollapsedInfiniteEventList :: (NonNeg.C time) =>+makeUncollapsedInfiniteEventList ::+   (NonNeg.C time, Num time) =>    NonEmptyList time body -> TimeBodyList.T time body makeUncollapsedInfiniteEventList =    makeInfiniteEventList .-   (\(time,body,xs) -> (time+1,body,xs))+   (\(time,body,xs) -> (add time 1, body, xs))  makeInfiniteEventList :: (NonNeg.C time) =>    NonEmptyList time body -> TimeBodyList.T time body@@ -826,17 +851,17 @@      quickCheck (mapBodyComposition toUpper toLower                :: TimeBodyList.T TimeDiff ArbChar -> Bool)) :    ("map time composition",-     quickCheck ((\dt0 dt1 -> mapTimeComposition (dt0+) (dt1+))+     quickCheck ((\dt0 dt1 -> mapTimeComposition (add dt0) (add dt1))                :: TimeDiff -> TimeDiff -> TimeBodyList.T TimeDiff ArbChar -> Bool)) :    ("map time body commutative",-     quickCheck ((\dt -> mapTimeBodyCommutative (dt+) toUpper)+     quickCheck ((\dt -> mapTimeBodyCommutative (add dt) toUpper)                :: TimeDiff -> TimeBodyList.T TimeDiff ArbChar -> Bool)) :     ("mapBodyInfinite",      quickCheck (mapBodyInfinite toUpper                :: NonEmptyList TimeDiff ArbChar -> Bool)) :    ("mapTimeInfinite",-     quickCheck (\dt -> mapTimeInfinite (dt+)+     quickCheck (\dt -> mapTimeInfinite (add dt)                :: NonEmptyList TimeDiff ArbChar -> Bool)) :     ("mapNormalize",@@ -894,6 +919,12 @@      quickCheck (takeTimeInfinite :: TimeDiff -> NonEmptyList TimeDiff ArbChar -> Bool)) :    ("dropTimeInfinite",      quickCheck (dropTimeInfinite :: TimeDiff -> NonEmptyList TimeDiff ArbChar -> Bool)) :+{-+   ("splitAtTimeLazyInfinite",+     quickCheck (splitAtTimeLazyInfinite :: BodyBodyList.T (NonNegChunky.T TimeDiff) ArbChar -> Bool)) :+   ("dropTimeLazyInfinite",+     quickCheck (dropTimeLazyInfinite :: BodyBodyList.T (NonNegChunky.T TimeDiff) ArbChar -> Bool)) :+-}     ("duration pause",      quickCheck (durationPause :: TimeDiff -> Bool)) :
src/Test/Data/EventList/Relative/TimeEnd.hs view
@@ -26,7 +26,7 @@  import qualified Numeric.NonNegative.Chunky as NonNegChunky import qualified Numeric.NonNegative.Class  as NonNeg-import Numeric.NonNegative.Class ((-|), )+import Numeric.NonNegative.Class ((-|), zero, add, ) import Data.EventList.Relative.TimeTime (isNormalized, )  import System.Random (Random, randomR, mkStdGen, )@@ -152,11 +152,88 @@    time -> body -> time -> time -> body -> time -> Bool consInfix t0a b0 t0b t1a b1 t1b =    TimeTimeList.append (t0a /. b0 ./ t0b /. empty) (t1a /. b1 ./ t1b /. empty)-      == (t0a /. b0 ./ (t0b+t1a) /. b1 ./ t1b /. empty)+      == (t0a /. b0 ./ (add t0b t1a) /. b1 ./ t1b /. empty)  +iterate' :: (a -> a) -> a -> [a]+iterate' f =+   let recourse x = ((:) $! x) $ recourse (f x)+   in  recourse +chunkyShow ::+   Int -> Bool+chunkyShow =+   (\t -> t==t) . take 1000000 . show .+   const (NonNegChunky.fromChunks $ iterate' (2-) (1::TimeDiff)) +_chunkyCheck ::+   Int -> Bool+_chunkyCheck =+   (\t -> t==t) .+   take 1000000 .+--   (!!1000000) .+{-+   NonNegChunky.toChunks .+   NonNegChunky.fromChunks .+-}+   iterate' (1+)++{-+With an early implementation of mapTimeTail this resulted in heap exhaustion.+-}+mapTimeTailChunkyInfinite ::+   (NonNeg.C time, Num time, Eq body, Show body) =>+   (body -> body) ->+   BodyTimeList.T (NonNegChunky.T time) body -> Bool+mapTimeTailChunkyInfinite _f =+   (\t -> t==t) . take 1000000 .+   NonNegChunky.toChunks .+   MixedTimeList.switchTimeL const .+{-+   MixedTimeList.switchTimeL+      MixedTimeList.consTime .+-}+   MixedTimeList.consTime+      (NonNegChunky.fromChunks $ iterate' (2-) 1)++{-+mapTimeTailChunkyInfinite ::+   (NonNeg.C time, Num time, Eq body, Show body) =>+   (body -> body) ->+   BodyTimeList.T (NonNegChunky.T time) body -> Bool+mapTimeTailChunkyInfinite f =+   (\t -> t==t) . take 1000000 . show .+   MixedTimeList.mapTimeTail (fmap f) .+   MixedTimeList.consTime+      (NonNegChunky.fromChunks $ iterate (2-) 1)+-}++{-+mapTimeTailChunkyInfinite :: (NonNeg.C time, Eq body) =>+   (body -> body) ->+   BodyTimeList.T (NonNegChunky.T time) body -> Bool+mapTimeTailChunkyInfinite f =+--   not . NonNegChunky.isNull .+--   not . null . NonNegChunky.toChunks .+   (\t -> t==t) . take 1000000 . NonNegChunky.toChunks .+   MixedTimeList.switchTimeL const .+--   TimeTimeList.dropTime 1000000 .+   MixedTimeList.mapTimeTail (fmap f) .+   MixedTimeList.consTime+      (NonNegChunky.fromChunks $ iterate (2-) 1)+++mapTimeTailChunkyInfinite :: (NonNeg.C time, Eq body) =>+   (body -> body) ->+   NonNegChunky.T time ->+   TimeTimeList.T (NonNegChunky.T time) body -> Bool+mapTimeTailChunkyInfinite f time =+   MixedTimeList.mapTimeTail (fmap f) .+   TimeTimeList.delay+      (let infTime = mappend time infTime in infTime)+-}++ mapBodyComposition :: (Eq body2, Eq time) =>    (body0 -> body1) -> (body1 -> body2) -> TimeTimeList.T time body0 -> Bool mapBodyComposition f g evs =@@ -203,12 +280,12 @@ appendLeftIdentity :: (NonNeg.C time, Eq body) =>    TimeTimeList.T time body -> Bool appendLeftIdentity xs =-   TimeTimeList.append (TimeTimeList.pause 0) xs  ==  xs+   TimeTimeList.append (TimeTimeList.pause zero) xs  ==  xs  appendRightIdentity :: (NonNeg.C time, Eq body) =>    TimeTimeList.T time body -> Bool appendRightIdentity xs =-   TimeTimeList.append xs (TimeTimeList.pause 0)  ==  xs+   TimeTimeList.append xs (TimeTimeList.pause zero)  ==  xs  appendAssociative :: (NonNeg.C time, Eq body) =>    TimeTimeList.T time body -> TimeTimeList.T time body -> TimeTimeList.T time body -> Bool@@ -220,7 +297,7 @@    time -> body -> TimeTimeList.T time body -> Bool appendCons time body xs =    TimeTimeList.cons time body xs  ==-   TimeTimeList.append (TimeTimeList.cons time body (TimeTimeList.pause 0)) xs+   TimeTimeList.append (TimeTimeList.cons time body (TimeTimeList.pause zero)) xs  appendSplitAtTime :: (NonNeg.C time, Eq body) =>    time -> TimeTimeList.T time body -> Bool@@ -261,13 +338,13 @@ delayAdditive :: (NonNeg.C time, Eq body) =>    time -> time -> TimeTimeList.T time body -> Bool delayAdditive dif0 dif1 xs =-   TimeTimeList.delay (dif0+dif1) xs ==+   TimeTimeList.delay (add dif0 dif1) xs ==    TimeTimeList.delay dif0 (TimeTimeList.delay dif1 xs)  delayPause :: (NonNeg.C time) =>    time -> time -> Bool delayPause dif0 dif1 =-   let pause = TimeTimeList.pause (dif0+dif1)+   let pause = TimeTimeList.pause (add dif0 dif1)    in  TimeTimeList.delay dif0 (TimeTimeList.pause dif1) ==        (asTypeOf pause (TimeTimeList.cons dif0 () pause)) @@ -294,9 +371,9 @@ takeTimeEndPause :: (NonNeg.C time, Ord body) =>    time -> TimeTimeList.T time body -> Bool takeTimeEndPause t xs =-   t == 0 ||+   t == zero ||    t >= TimeTimeList.duration xs ||-   0 <  snd (TimeMixedList.viewTimeR (TimeTimeList.takeTime t xs))+   zero <  snd (TimeMixedList.viewTimeR (TimeTimeList.takeTime t xs))  takeTimeAppendFirst :: (NonNeg.C time, Eq body) =>    time -> TimeTimeList.T time body -> TimeTimeList.T time body -> Bool@@ -306,7 +383,7 @@       (TimeTimeList.takeTime t xs)       (TimeTimeList.takeTime (t -| TimeTimeList.duration xs) ys) -takeTimeAppendSecond :: (NonNeg.C time, Eq body) =>+takeTimeAppendSecond :: (NonNeg.C time, Num time, Eq body) =>    time -> TimeTimeList.T time body -> TimeTimeList.T time body -> Bool takeTimeAppendSecond t xs0 ys =    -- the first list must not end with a zero pause@@ -324,20 +401,58 @@ dropTimeNormalize t =    isNormalized . TimeTimeList.dropTime t . TimeTimeList.normalize -takeTimeInfinite :: (NonNeg.C time, Ord body) =>+takeTimeInfinite :: (NonNeg.C time, Num time, Ord body) =>    time -> NonEmptyList time body -> Bool takeTimeInfinite t =    (t == ) . TimeTimeList.duration .    TimeTimeList.takeTime t . makeUncollapsedInfiniteEventList -dropTimeInfinite :: (NonNeg.C time, Ord body) =>+dropTimeInfinite :: (NonNeg.C time, Num time, Ord body) =>    time -> NonEmptyList time body -> Bool dropTimeInfinite t =    checkInfinite . TimeTimeList.dropTime t . makeUncollapsedInfiniteEventList +dropTimeLargeInfinite ::+   (NonNeg.C time, Num time, Ord body) =>+   NonEmptyList time body -> Bool+dropTimeLargeInfinite =+   checkInfinite .+   TimeTimeList.dropTime 10000 .+   makeUncollapsedInfiniteEventList  +splitAtTimeLazyInfinite ::+   (NonNeg.C time, Num time, Ord body, Show time, Show body) =>+   BodyTimeList.T (NonNegChunky.T time) body -> Bool+splitAtTimeLazyInfinite =+   not . null . show . snd .+   TimeTimeList.splitAtTime 1000000 .+   MixedTimeList.consTime+      (NonNegChunky.fromChunks $ iterate (2-) 1) +dropTimeLazyInfinite ::+   (NonNeg.C time, Num time, Ord body, Show time, Show body) =>+   BodyTimeList.T (NonNegChunky.T time) body -> Bool+dropTimeLazyInfinite =+   not . null . show .+   TimeTimeList.dropTime 1000000 .+   MixedTimeList.consTime+      (NonNegChunky.fromChunks $ iterate (2-) 1)++{-+dropTimeLazyInfinite ::+   (NonNeg.C time, Num time, Ord body) =>+   BodyTimeList.T (NonNegChunky.T time) body -> Bool+dropTimeLazyInfinite =+   (\t -> t==t) . take 100 . NonNegChunky.toChunks .+   MixedTimeList.switchTimeL const .+   TimeTimeList.dropTime 1000000 .+   MixedTimeList.consTime+      (NonNegChunky.fromChunks $ iterate (2-) 1)+-}+++ durationPause :: (NonNeg.C time) =>    time -> Bool durationPause t =@@ -347,7 +462,7 @@    TimeTimeList.T time body -> TimeTimeList.T time body -> Bool durationAppend xs ys =    TimeTimeList.duration (TimeTimeList.append xs ys)  ==-   TimeTimeList.duration xs + TimeTimeList.duration ys+   TimeTimeList.duration xs `add` TimeTimeList.duration ys  durationMerge :: (NonNeg.C time, Ord body) =>    TimeTimeList.T time body -> TimeTimeList.T time body -> Bool@@ -394,20 +509,20 @@    in  equalPrefix 100 xs (TimeTimeList.cycle xs)  -filterSatisfy :: (Num time) =>+filterSatisfy :: (NonNeg.C time) =>    (body -> Bool) ->    TimeTimeList.T time body -> Bool filterSatisfy p =    all p . TimeTimeList.getBodies . TimeTimeList.filter p -filterProjection :: (Num time, Eq body) =>+filterProjection :: (NonNeg.C time, Eq body) =>    (body -> Bool) ->    TimeTimeList.T time body -> Bool filterProjection p xs =    TimeTimeList.filter p xs ==    TimeTimeList.filter p (TimeTimeList.filter p xs) -filterCommutative :: (Num time, Eq body) =>+filterCommutative :: (NonNeg.C time, Eq body) =>    (body -> Bool) ->    (body -> Bool) ->    TimeTimeList.T time body -> Bool@@ -415,7 +530,7 @@    TimeTimeList.filter p (TimeTimeList.filter q xs) ==    TimeTimeList.filter q (TimeTimeList.filter p xs) -filterComposition :: (Num time, Eq body) =>+filterComposition :: (NonNeg.C time, Eq body) =>    (body -> Bool) ->    (body -> Bool) ->    TimeTimeList.T time body -> Bool@@ -464,23 +579,23 @@    TimeTimeList.append (TimeTimeList.catMaybes xs) (TimeTimeList.catMaybes ys)  -catMaybesRInfinite :: (NonNeg.C time, Eq body) =>+catMaybesRInfinite :: (NonNeg.C time, Num time, Eq body) =>    NonEmptyList time (Maybe body) -> Bool catMaybesRInfinite xs =    {--   @(1+) is needed in order to assert that the accumulated time is infinite+   @(add 1) is needed in order to assert that the accumulated time is infinite    and can be clipped by @min 100@.    -}    let t =          min 100 $-         List.foldr (+) 0 $+         List.foldr add zero $          TimeTimeList.getTimes $          TimeTimeList.catMaybesR $-         TimeTimeList.mapTime (NonNegChunky.fromNumber . (1+)) $+         TimeTimeList.mapTime (NonNegChunky.fromNumber . (add 1)) $          makeInfiniteEventList xs    in  t == t -catMaybesRInitInfinite :: (NonNeg.C time, Eq body) =>+catMaybesRInitInfinite :: (NonNeg.C time, Num time, Eq body) =>    NonEmptyList time body -> Bool catMaybesRInitInfinite xs =    let t =@@ -488,7 +603,7 @@          MixedTimeList.switchTimeL const $          TimeTimeList.catMaybesR $          TimeTimeList.mapBody (const (Nothing::Maybe())) $-         TimeTimeList.mapTime (NonNegChunky.fromNumber . (1+)) $+         TimeTimeList.mapTime (NonNegChunky.fromNumber . (add 1)) $          makeInfiniteEventList xs    in  t == t @@ -506,27 +621,27 @@    TimeTimeList.partitionMaybeR f xs  partitionMaybeRInfinite ::-   (NonNeg.C time, Eq body0, Eq body1) =>+   (NonNeg.C time, Num time, Eq body0, Eq body1) =>    (body0 -> Maybe body1) ->    NonEmptyList time body0 -> Bool partitionMaybeRInfinite f xs =    {--   @(1+) is needed in order to assert that the accumulated time is infinite+   @(add 1) is needed in order to assert that the accumulated time is infinite    and can be clipped by @min 100@.    -}    let timeSum =          min 100 .-         List.foldr (+) 0 .+         List.foldr add zero .          TimeTimeList.getTimes        t =          mapPair (timeSum, timeSum) $          TimeTimeList.partitionMaybeR f $-         TimeTimeList.mapTime (NonNegChunky.fromNumber . (1+)) $+         TimeTimeList.mapTime (NonNegChunky.fromNumber . add 1) $          makeInfiniteEventList xs    in  t == t  partitionMaybeRInitInfinite ::-   (NonNeg.C time, Eq body0, Eq body1) =>+   (NonNeg.C time, Num time, Eq body0, Eq body1) =>    (body0 -> Maybe body1) ->    NonEmptyList time body0 -> Bool partitionMaybeRInitInfinite f xs =@@ -536,7 +651,7 @@        t =          mapPair (initTime, initTime) $          TimeTimeList.partitionMaybeR f $-         TimeTimeList.mapTime (NonNegChunky.fromNumber . (1+)) $+         TimeTimeList.mapTime (NonNegChunky.fromNumber . add 1) $          makeInfiniteEventList xs    in  t == t @@ -554,12 +669,12 @@ mergeLeftIdentity :: (NonNeg.C time, Ord body) =>    TimeTimeList.T time body -> Bool mergeLeftIdentity xs =-   TimeTimeList.merge (TimeTimeList.pause 0) xs  ==  xs+   TimeTimeList.merge (TimeTimeList.pause zero) xs  ==  xs  mergeRightIdentity :: (NonNeg.C time, Ord body) =>    TimeTimeList.T time body -> Bool mergeRightIdentity xs =-   TimeTimeList.merge xs (TimeTimeList.pause 0)  ==  xs+   TimeTimeList.merge xs (TimeTimeList.pause zero)  ==  xs  mergeCommutative :: (NonNeg.C time, Ord body) =>    TimeTimeList.T time body -> TimeTimeList.T time body -> Bool@@ -698,7 +813,7 @@ insertMerge time body evs0 =    let evs = TimeTimeList.normalize evs0    in  TimeTimeList.insert time body evs  ==-       TimeTimeList.merge (TimeTimeList.cons time body $ TimeTimeList.pause 0) evs+       TimeTimeList.merge (TimeTimeList.cons time body $ TimeTimeList.pause zero) evs  insertNormalize :: (NonNeg.C time, Ord body) =>    time -> body -> TimeTimeList.T time body -> Bool@@ -714,7 +829,7 @@    ==       let (prefix,suffix) = TimeTimeList.splitAtTime time evs       in  TimeTimeList.normalize-             (TimeTimeList.append prefix (TimeTimeList.cons 0 body suffix))+             (TimeTimeList.append prefix (TimeTimeList.cons zero body suffix))       --  append prefix (MixedTimeList.consBody body suffix)  insertInfinite :: (NonNeg.C time, Ord body) =>@@ -725,21 +840,21 @@   -moveForwardIdentity :: (NonNeg.C time, Ord body) =>+moveForwardIdentity :: (NonNeg.C time, Num time, Ord body) =>    TimeTimeList.T time body -> Bool moveForwardIdentity evs =    evs ==-   TimeTimeList.moveForward (TimeTimeList.mapBody ((,) 0) evs)+   TimeTimeList.moveForward (TimeTimeList.mapBody ((,) zero) evs) -moveForwardAdditive :: (NonNeg.C time, Ord body) =>+moveForwardAdditive :: (NonNeg.C time, Num time, Ord body) =>    TimeTimeList.T time ((time,time),body) -> Bool moveForwardAdditive evs =    TimeTimeList.normalize (moveForwardLimited (moveForwardLimited       (TimeTimeList.mapBody (\((t0,t1),b) -> (t0,(t1,b))) evs))) ==    TimeTimeList.normalize (moveForwardLimited-      (TimeTimeList.mapBody (mapFst (uncurry (+))) evs))+      (TimeTimeList.mapBody (mapFst (uncurry add)) evs)) -moveForwardCommutative :: (NonNeg.C time, Ord body) =>+moveForwardCommutative :: (NonNeg.C time, Num time, Ord body) =>    TimeTimeList.T time ((time,time),body) -> Bool moveForwardCommutative evs =    TimeTimeList.normalize (moveForwardLimited (moveForwardLimited@@ -747,7 +862,7 @@    TimeTimeList.normalize (moveForwardLimited (moveForwardLimited       (TimeTimeList.mapBody (\((t0,t1),b) -> (t1,(t0,b))) evs))) -moveForwardRestricted :: (NonNeg.C time, Ord body) =>+moveForwardRestricted :: (NonNeg.C time, Num time, Ord body) =>    time -> TimeTimeList.T time (time,body) -> Bool moveForwardRestricted maxTime evs0 =    let evs =@@ -758,7 +873,8 @@        &&  mevs  ==  TimeTimeList.moveForwardRestrictedByStrict (\_ _ -> True) maxTime evs        &&  mevs  ==  TimeTimeList.moveForwardRestrictedByQueue (\_ _ -> False) maxTime evs -moveForwardRestrictedInfinity :: (NonNeg.C time, Ord body) =>+moveForwardRestrictedInfinity ::+   (NonNeg.C time, Num time, Ord body) =>    time -> NonEmptyList time (time,body) -> Bool moveForwardRestrictedInfinity maxTime =    checkInfinite .@@ -769,16 +885,16 @@   -moveForwardLimited :: (NonNeg.C time) =>+moveForwardLimited :: (NonNeg.C time, Num time) =>    TimeTimeList.T time (time,body) -> TimeTimeList.T time body moveForwardLimited = TimeTimeList.moveForward . restrictMoveTimes  restrictMoveTimes :: (NonNeg.C time) =>    TimeTimeList.T time (time,body) -> TimeTimeList.T time (time,body) restrictMoveTimes =-   flip evalState 0 .+   flip evalState zero .    TimeTimeList.mapM-      (\t -> modify (t+) >> return t)+      (\t -> modify (add t) >> return t)       (\(t,b) -> gets (\tm -> (min t tm, b)))  @@ -788,7 +904,7 @@    evs ==    TimeTimeList.arrange       (TimeTimeList.mapBody-          (\x -> TimeTimeList.cons 0 x (TimeTimeList.pause 0)) evs)+          (\x -> TimeTimeList.cons zero x (TimeTimeList.pause zero)) evs)  arrangeDelay :: (NonNeg.C time, Ord body) =>    time -> NonEmptyList time body -> Bool@@ -797,8 +913,8 @@    in  TimeTimeList.delay delay evs ==        TimeTimeList.arrange           (TimeTimeList.mapBody-              (\x -> TimeTimeList.cons delay x (TimeTimeList.pause 0)) $-           TimeTimePriv.mapTimeLast (delay+) evs)+              (\x -> TimeTimeList.cons delay x (TimeTimeList.pause zero)) $+           TimeTimePriv.mapTimeLast (add delay) evs)  arrangeSimple :: (NonNeg.C time, Ord body) =>    TimeTimeList.T time (TimeTimeList.T time body) ->@@ -809,10 +925,10 @@    TimeTimeList.foldr       (TimeTimeList.delay)       (TimeTimeList.merge)-      (TimeTimeList.pause 0)+      (TimeTimeList.pause zero)       (TimeTimeList.mapBody TimeTimeList.normalize evs) -arrangeAbsolute :: (NonNeg.C time, Ord body) =>+arrangeAbsolute :: (NonNeg.C time, Num time, Ord body) =>    TimeTimeList.T time (TimeTimeList.T time body) ->    Bool arrangeAbsolute evs =@@ -822,10 +938,10 @@           TimeTimeList.merge              (TimeTimeList.delay t (TimeTimeList.normalize xs)) ys)       (,)-      (TimeTimeList.pause 0, TimeTimeList.pause 0)-      (TimeTimeList.toAbsoluteEventList 0 evs)+      (TimeTimeList.pause zero, TimeTimeList.pause zero)+      (TimeTimeList.toAbsoluteEventList zero evs) -arrangeInfinity :: (NonNeg.C time, Ord body) =>+arrangeInfinity :: (NonNeg.C time, Num time, Ord body) =>    NonEmptyList time (NonEmptyList time body) -> Bool arrangeInfinity =    checkInfinite .@@ -845,14 +961,14 @@    TimeTimeList.T time body -> Bool collectCoincidentGaps xs =    let times = tail (TimeTimeList.getTimes (TimeTimeList.collectCoincident xs))-   in  null times || all (0<) (init times)+   in  null times || all (zero<) (init times)  collectCoincidentNonEmpty :: (NonNeg.C time, Eq body) =>    TimeTimeList.T time body -> Bool collectCoincidentNonEmpty =    all (not . null) . TimeTimeList.getBodies . TimeTimeList.collectCoincident -collectCoincidentInfinite :: (NonNeg.C time, Eq body) =>+collectCoincidentInfinite :: (NonNeg.C time, Num time, Eq body) =>    NonEmptyList time body -> Bool collectCoincidentInfinite =    checkInfinite .@@ -975,7 +1091,7 @@ discretize :: (RealFrac time, Integral i) =>    TimeTimeList.T time body -> TimeTimeList.T i body discretize es =-   evalState (Uniform.mapSecondM roundDiff es) 0+   evalState (Uniform.mapSecondM roundDiff es) zero  resample :: (RealFrac time, Integral i) =>    time -> TimeTimeList.T time body -> TimeTimeList.T i body@@ -988,7 +1104,7 @@ toAbsoluteEventList start xs =    let ts = Uniform.getSeconds xs        bs = Uniform.getFirsts  xs-       ats = List.scanl (+) start ts+       ats = List.scanl add start ts    in  maybe           (error "padded list always contains one time value")           (\ ~(ats0,lt) -> (zip ats0 bs, lt))@@ -1000,11 +1116,12 @@  type NonEmptyList time body = (time, body, TimeTimeList.T time body) -makeUncollapsedInfiniteEventList :: (NonNeg.C time) =>+makeUncollapsedInfiniteEventList ::+   (NonNeg.C time, Num time) =>    NonEmptyList time body -> TimeTimeList.T time body makeUncollapsedInfiniteEventList =    makeInfiniteEventList .-   (\(time,body,xs) -> (time+1,body,xs))+   (\(time,body,xs) -> (add time 1, body, xs))  makeInfiniteEventList :: (NonNeg.C time) =>    NonEmptyList time body -> TimeTimeList.T time body@@ -1071,23 +1188,31 @@      quickCheck (snocTimeBodyInfinite :: TimeDiff -> ArbChar -> NonEmptyList TimeDiff ArbChar -> Bool)) :    ("consInfix",      quickCheck (consInfix :: TimeDiff -> ArbChar -> TimeDiff -> TimeDiff -> ArbChar -> TimeDiff -> Bool)) :+   ("chunkyShow",+     quickCheck chunkyShow) :+{-+   ("chunkyCheck",+     quickCheck chunkyCheck) :+-}+   ("mapTimeTailChunkyInfinite",+     quickCheck (mapTimeTailChunkyInfinite succ :: BodyTimeList.T (NonNegChunky.T TimeDiff) ArbChar -> Bool)) :      ("map body composition",      quickCheck (mapBodyComposition toUpper toLower                :: TimeTimeList.T TimeDiff ArbChar -> Bool)) :    ("map time composition",-     quickCheck ((\dt0 dt1 -> mapTimeComposition (dt0+) (dt1+))+     quickCheck ((\dt0 dt1 -> mapTimeComposition (add dt0) (add dt1))                :: TimeDiff -> TimeDiff -> TimeTimeList.T TimeDiff ArbChar -> Bool)) :    ("map time body commutative",-     quickCheck ((\dt -> mapTimeBodyCommutative (dt+) toUpper)+     quickCheck ((\dt -> mapTimeBodyCommutative (add dt) toUpper)                :: TimeDiff -> TimeTimeList.T TimeDiff ArbChar -> Bool)) :     ("mapBodyInfinite",      quickCheck (mapBodyInfinite toUpper                :: NonEmptyList TimeDiff ArbChar -> Bool)) :    ("mapTimeInfinite",-     quickCheck (\dt -> mapTimeInfinite (dt+)+     quickCheck (\dt -> mapTimeInfinite (add dt)                :: NonEmptyList TimeDiff ArbChar -> Bool)) :     ("mapNormalize",@@ -1151,6 +1276,12 @@      quickCheck (takeTimeInfinite :: TimeDiff -> NonEmptyList TimeDiff ArbChar -> Bool)) :    ("dropTimeInfinite",      quickCheck (dropTimeInfinite :: TimeDiff -> NonEmptyList TimeDiff ArbChar -> Bool)) :+   ("dropTimeLargeInfinite",+     quickCheck (dropTimeLargeInfinite :: NonEmptyList TimeDiff ArbChar -> Bool)) :+   ("splitAtTimeLazyInfinite",+     quickCheck (splitAtTimeLazyInfinite :: BodyTimeList.T (NonNegChunky.T TimeDiff) ArbChar -> Bool)) :+   ("dropTimeLazyInfinite",+     quickCheck (dropTimeLazyInfinite :: BodyTimeList.T (NonNegChunky.T TimeDiff) ArbChar -> Bool)) :     ("duration pause",      quickCheck (durationPause :: TimeDiff -> Bool)) :
src/Test/Main.hs view
@@ -5,16 +5,20 @@ import qualified Test.Data.EventList.Relative.BodyEnd as RelBodyEnd import qualified Test.Data.EventList.Relative.TimeEnd as RelTimeEnd +import qualified System.IO as IO++ prefix :: String -> [(String, IO ())] -> [(String, IO ())] prefix msg =    map (\(str,test) -> (msg ++ "." ++ str, test))  main :: IO () main =-   mapM_ (\(msg,io) -> putStr (msg++": ") >> io) $-   concat $-      prefix "Absolute.BodyEnd" AbsBodyEnd.tests :-      prefix "Absolute.TimeEnd" AbsTimeEnd.tests :-      prefix "Relative.BodyEnd" RelBodyEnd.tests :-      prefix "Relative.TimeEnd" RelTimeEnd.tests :-      []+   IO.hSetBuffering IO.stdout IO.NoBuffering >>+   (mapM_ (\(msg,io) -> putStr (msg++": ") >> io) $+    concat $+       prefix "Absolute.BodyEnd" AbsBodyEnd.tests :+       prefix "Absolute.TimeEnd" AbsTimeEnd.tests :+       prefix "Relative.BodyEnd" RelBodyEnd.tests :+       prefix "Relative.TimeEnd" RelTimeEnd.tests :+       [])