module Data.TimeSeries.Sessions ( Session(..) , find ) where import Data.Time (UTCTime) import Data.TimeSeries.Series (Series, toList) import Data.TimeSeries.Time(TimeResolution, nextTime) -- | Session is a time range of a single event -- Some examples: -- * Session with web application -- * Rain event data Session = Session { sessionStart :: UTCTime , sessionEnd :: UTCTime } deriving (Eq, Show) -- | Find all session in a given time series find :: TimeResolution -> Series Bool -> [Session] find dt ts = map (uncurry Session) xs' where xs = findChanges False (toList ts) xs' = join dt (cnv xs) -- Helper function for finding all places where value changes from True to False or vice versa findChanges :: Bool -> [(a, Bool)] -> [a] findChanges _ [] = [] findChanges True [x] = [fst x] findChanges v (x:xs) | v == snd x = findChanges v xs | otherwise = fst x : findChanges (snd x) xs -- Convert list of changes into tuple2 cnv :: [a] -> [(a, a)] cnv [] = [] cnv [_] = [] cnv (x:y:z) = (x, y) : cnv z -- Join events close to each other into single session join :: TimeResolution -> [(UTCTime, UTCTime)] -> [(UTCTime, UTCTime)] join _ [] = [] join _ [x] = [x] join dt (x:y:z) = if nextTime dt (snd x) < fst y then x:join dt (y:z) else join dt ((fst x, snd y):z)