#!/usr/bin/env stack > --stack --install-ghc runghc > module ParseTime ( > count_down_time, > subtract_second, > asTimePeriod > ) > where > > data TimePeriod = TimePeriod Integer Integer deriving (Read) > > split :: (Char -> Bool) -> String -> [String] > split p s = case dropWhile p s of > "" -> [] > s' -> w : split p s'' > where (w, s'') = break p s' > -- | Given a string denoting a time interval, function "split" returns the > -- corresponding time in ["MM","SS"]. > -- > -- >>> split (==':') "10:20" > -- ["10","20"] > split_by_colon :: String -> [String] > split_by_colon timeString = split (==':') timeString > > {-| split_by_colon: Returns time in `["MM","SS"]`, corresponding to the time > interval given in a string. > > >>> split_by_colon "10:20" > ["10","20"] > -} > > many_to_int :: [String] -> [Integer] > many_to_int [] = [] > many_to_int (x:xs) = (read $ x :: Integer):(many_to_int xs) > > {-| many_to_int > > >>> many_to_int ["10","20"] > [10,20] > -} > > list_to_time_periods :: [Integer] -> [TimePeriod] > list_to_time_periods [m,s] = [TimePeriod m s] > list_to_time_periods _ = [] > > {-| list_to_time_periods > > >>> list_to_time_periods [10,20] > [10:20] > -} > > subtract_second :: TimePeriod -> TimePeriod > subtract_second (TimePeriod 0 0) = TimePeriod 0 0 > subtract_second (TimePeriod 0 s) = TimePeriod 0 (s-1) > subtract_second (TimePeriod m 0) = TimePeriod (m-1) 59 > subtract_second (TimePeriod m s) = TimePeriod m (s-1) > > {-| subtract_second: Given a TimePeriod, returns a TimePeriod that is one > second shorter. > > >>> subtract_second $ TimePeriod 00 00 > 00:00 > > >>> subtract_second $ TimePeriod 00 01 > 00:00 > > >>> subtract_second $ TimePeriod 01 00 > 00:59 > > >>> subtract_second $ TimePeriod 02 00 > 01:59 > -} > > asTimePeriod :: String -> TimePeriod > asTimePeriod s = head $ list_to_time_periods $ many_to_int $ split_by_colon s > > {-| asTimePeriod: Reads a string as a TimePeriod. > > >>> asTimePeriod "00:00" > 00:00 > > >>> asTimePeriod "99:99" > 99:99 > -} > > {-| count_down_time: Subtracts a second from time given as a string. > > >>> count_down_time "00:00" > "00:00" > > >>> count_down_time "00:01" > "00:00" > > >>> count_down_time "00:02" > "00:01" > > >>> count_down_time "01:00" > "00:59" > -} > > count_down_time :: String -> String > count_down_time = show . subtract_second . asTimePeriod > > {-| show_two_digits > > >>> show_two_digits 0 > "00" > -} > > show_two_digits :: Integer -> String > show_two_digits x > | x < 10 = "0" ++ show x > | otherwise = show x > > {-| show TimePeriod > > >>> show (TimePeriod 0 0) > "00:00" > > >>> a = TimePeriod 0 0 > >>> show a > "00:00" > -} > > instance Show TimePeriod where > show (TimePeriod m s) = show_two_digits m ++ ":" ++ show_two_digits s Related materials: 1. Generic time processing example: https://stackoverflow.com/a/14006938