module Sound.Audacity.LabelTrack where
import Text.Read.HT (maybeRead)
import Text.Printf (printf)
import Control.DeepSeq (NFData, rnf)
import Control.Monad (zipWithM)
import qualified Data.Traversable as Trav
import qualified Data.Foldable as Fold
import qualified Data.Monoid as Mn
import qualified Data.Semigroup as Sg
import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.List.HT as ListHT
import Data.Tuple.HT (mapFst, mapSnd, mapPair)
import qualified Prelude as P
import Prelude hiding (readFile, writeFile, null)
newtype T time label = Cons {T time label -> [Interval time label]
decons :: [Interval time label]}
instance (Show time, Show label) => Show (T time label) where
showsPrec :: Int -> T time label -> ShowS
showsPrec Int
p (Cons [Interval time label]
xs) =
Bool -> ShowS -> ShowS
showParen (Int
pInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String -> ShowS
showString String
"LabelTrack.Cons " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Interval time label] -> ShowS
forall a. Show a => a -> ShowS
shows [Interval time label]
xs
type Interval time label = ((time, time), label)
instance Functor (T time) where
fmap :: (a -> b) -> T time a -> T time b
fmap a -> b
f = ([Interval time a] -> [Interval time b]) -> T time a -> T time b
forall time0 label0 time1 label1.
([Interval time0 label0] -> [Interval time1 label1])
-> T time0 label0 -> T time1 label1
lift (([Interval time a] -> [Interval time b]) -> T time a -> T time b)
-> ([Interval time a] -> [Interval time b]) -> T time a -> T time b
forall a b. (a -> b) -> a -> b
$ (Interval time a -> Interval time b)
-> [Interval time a] -> [Interval time b]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> b) -> Interval time a -> Interval time b
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd a -> b
f)
instance Fold.Foldable (T time) where
foldMap :: (a -> m) -> T time a -> m
foldMap a -> m
f = (((time, time), a) -> m) -> [((time, time), a)] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
Fold.foldMap (a -> m
f (a -> m) -> (((time, time), a) -> a) -> ((time, time), a) -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((time, time), a) -> a
forall a b. (a, b) -> b
snd) ([((time, time), a)] -> m)
-> (T time a -> [((time, time), a)]) -> T time a -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T time a -> [((time, time), a)]
forall time label. T time label -> [Interval time label]
decons
instance Trav.Traversable (T time) where
sequenceA :: T time (f a) -> f (T time a)
sequenceA =
([Interval time a] -> T time a)
-> f [Interval time a] -> f (T time a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Interval time a] -> T time a
forall time label. [Interval time label] -> T time label
Cons (f [Interval time a] -> f (T time a))
-> (T time (f a) -> f [Interval time a])
-> T time (f a)
-> f (T time a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((time, time), f a) -> f (Interval time a))
-> [((time, time), f a)] -> f [Interval time a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
Trav.traverse (\((time, time)
bnd, f a
label) -> (a -> Interval time a) -> f a -> f (Interval time a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((,) (time, time)
bnd) f a
label) ([((time, time), f a)] -> f [Interval time a])
-> (T time (f a) -> [((time, time), f a)])
-> T time (f a)
-> f [Interval time a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T time (f a) -> [((time, time), f a)]
forall time label. T time label -> [Interval time label]
decons
instance Sg.Semigroup (T time label) where
Cons [Interval time label]
xs <> :: T time label -> T time label -> T time label
<> Cons [Interval time label]
ys = [Interval time label] -> T time label
forall time label. [Interval time label] -> T time label
Cons ([Interval time label] -> T time label)
-> [Interval time label] -> T time label
forall a b. (a -> b) -> a -> b
$ [Interval time label]
xs [Interval time label]
-> [Interval time label] -> [Interval time label]
forall a. [a] -> [a] -> [a]
++ [Interval time label]
ys
sconcat :: NonEmpty (T time label) -> T time label
sconcat = [Interval time label] -> T time label
forall time label. [Interval time label] -> T time label
Cons ([Interval time label] -> T time label)
-> (NonEmpty (T time label) -> [Interval time label])
-> NonEmpty (T time label)
-> T time label
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (T time label -> [Interval time label])
-> [T time label] -> [Interval time label]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap T time label -> [Interval time label]
forall time label. T time label -> [Interval time label]
decons ([T time label] -> [Interval time label])
-> (NonEmpty (T time label) -> [T time label])
-> NonEmpty (T time label)
-> [Interval time label]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (T time label) -> [T time label]
forall a. NonEmpty a -> [a]
NonEmpty.toList
instance Mn.Monoid (T time label) where
mempty :: T time label
mempty = T time label
forall time label. T time label
empty
mappend :: T time label -> T time label -> T time label
mappend (Cons [Interval time label]
xs) (Cons [Interval time label]
ys) = [Interval time label] -> T time label
forall time label. [Interval time label] -> T time label
Cons ([Interval time label] -> T time label)
-> [Interval time label] -> T time label
forall a b. (a -> b) -> a -> b
$ [Interval time label]
xs [Interval time label]
-> [Interval time label] -> [Interval time label]
forall a. [a] -> [a] -> [a]
++ [Interval time label]
ys
mconcat :: [T time label] -> T time label
mconcat = [Interval time label] -> T time label
forall time label. [Interval time label] -> T time label
Cons ([Interval time label] -> T time label)
-> ([T time label] -> [Interval time label])
-> [T time label]
-> T time label
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (T time label -> [Interval time label])
-> [T time label] -> [Interval time label]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap T time label -> [Interval time label]
forall time label. T time label -> [Interval time label]
decons
instance (NFData time, NFData label) => NFData (T time label) where
rnf :: T time label -> ()
rnf = [Interval time label] -> ()
forall a. NFData a => a -> ()
rnf ([Interval time label] -> ())
-> (T time label -> [Interval time label]) -> T time label -> ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T time label -> [Interval time label]
forall time label. T time label -> [Interval time label]
decons
empty :: T time label
empty :: T time label
empty = [Interval time label] -> T time label
forall time label. [Interval time label] -> T time label
Cons []
null :: T time label -> Bool
null :: T time label -> Bool
null = [Interval time label] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
P.null ([Interval time label] -> Bool)
-> (T time label -> [Interval time label]) -> T time label -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T time label -> [Interval time label]
forall time label. T time label -> [Interval time label]
decons
singleton :: (time,time) -> label -> T time label
singleton :: (time, time) -> label -> T time label
singleton (time, time)
bnds label
label = [Interval time label] -> T time label
forall time label. [Interval time label] -> T time label
Cons [((time, time)
bnds, label
label)]
fromAdjacentChunks ::
(Num time) => [(time, label)] -> T time label
fromAdjacentChunks :: [(time, label)] -> T time label
fromAdjacentChunks =
[Interval time label] -> T time label
forall time label. [Interval time label] -> T time label
Cons ([Interval time label] -> T time label)
-> ([(time, label)] -> [Interval time label])
-> [(time, label)]
-> T time label
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (time, [Interval time label]) -> [Interval time label]
forall a b. (a, b) -> b
snd ((time, [Interval time label]) -> [Interval time label])
-> ([(time, label)] -> (time, [Interval time label]))
-> [(time, label)]
-> [Interval time label]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(time -> (time, label) -> (time, Interval time label))
-> time -> [(time, label)] -> (time, [Interval time label])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
Trav.mapAccumL (\time
t0 (time
d, label
lab) -> let t1 :: time
t1=time
t0time -> time -> time
forall a. Num a => a -> a -> a
+time
d in (time
t1, ((time
t0,time
t1), label
lab))) time
0
lift ::
([Interval time0 label0] -> [Interval time1 label1]) ->
T time0 label0 -> T time1 label1
lift :: ([Interval time0 label0] -> [Interval time1 label1])
-> T time0 label0 -> T time1 label1
lift [Interval time0 label0] -> [Interval time1 label1]
f (Cons [Interval time0 label0]
xs) = [Interval time1 label1] -> T time1 label1
forall time label. [Interval time label] -> T time label
Cons ([Interval time1 label1] -> T time1 label1)
-> [Interval time1 label1] -> T time1 label1
forall a b. (a -> b) -> a -> b
$ [Interval time0 label0] -> [Interval time1 label1]
f [Interval time0 label0]
xs
lift2 ::
([Interval time0 label0] -> [Interval time1 label1] -> [Interval time2 label2]) ->
T time0 label0 -> T time1 label1 -> T time2 label2
lift2 :: ([Interval time0 label0]
-> [Interval time1 label1] -> [Interval time2 label2])
-> T time0 label0 -> T time1 label1 -> T time2 label2
lift2 [Interval time0 label0]
-> [Interval time1 label1] -> [Interval time2 label2]
f (Cons [Interval time0 label0]
xs) (Cons [Interval time1 label1]
ys) = [Interval time2 label2] -> T time2 label2
forall time label. [Interval time label] -> T time label
Cons ([Interval time2 label2] -> T time2 label2)
-> [Interval time2 label2] -> T time2 label2
forall a b. (a -> b) -> a -> b
$ [Interval time0 label0]
-> [Interval time1 label1] -> [Interval time2 label2]
f [Interval time0 label0]
xs [Interval time1 label1]
ys
formatTime :: (RealFrac time) => time -> String
formatTime :: time -> String
formatTime time
t =
let million :: Integer
million = Integer
10Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^(Int
6::Int)
(Integer
seconds,Integer
micros) = Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
divMod (time -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round (time
t time -> time -> time
forall a. Num a => a -> a -> a
* Integer -> time
forall a. Num a => Integer -> a
fromInteger Integer
million)) Integer
million
in String -> Integer -> Integer -> String
forall r. PrintfType r => String -> r
printf String
"%d,%06d" Integer
seconds Integer
micros
mapTime :: (time0 -> time1) -> T time0 label -> T time1 label
mapTime :: (time0 -> time1) -> T time0 label -> T time1 label
mapTime time0 -> time1
f = ([Interval time0 label] -> [Interval time1 label])
-> T time0 label -> T time1 label
forall time0 label0 time1 label1.
([Interval time0 label0] -> [Interval time1 label1])
-> T time0 label0 -> T time1 label1
lift (([Interval time0 label] -> [Interval time1 label])
-> T time0 label -> T time1 label)
-> ([Interval time0 label] -> [Interval time1 label])
-> T time0 label
-> T time1 label
forall a b. (a -> b) -> a -> b
$ (Interval time0 label -> Interval time1 label)
-> [Interval time0 label] -> [Interval time1 label]
forall a b. (a -> b) -> [a] -> [b]
map (((time0, time0) -> (time1, time1))
-> Interval time0 label -> Interval time1 label
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (((time0, time0) -> (time1, time1))
-> Interval time0 label -> Interval time1 label)
-> ((time0, time0) -> (time1, time1))
-> Interval time0 label
-> Interval time1 label
forall a b. (a -> b) -> a -> b
$ (time0 -> time1, time0 -> time1)
-> (time0, time0) -> (time1, time1)
forall a c b d. (a -> c, b -> d) -> (a, b) -> (c, d)
mapPair (time0 -> time1
f, time0 -> time1
f))
mapWithTime ::
((time, time) -> label0 -> label1) -> T time label0 -> T time label1
mapWithTime :: ((time, time) -> label0 -> label1)
-> T time label0 -> T time label1
mapWithTime (time, time) -> label0 -> label1
f = ([Interval time label0] -> [Interval time label1])
-> T time label0 -> T time label1
forall time0 label0 time1 label1.
([Interval time0 label0] -> [Interval time1 label1])
-> T time0 label0 -> T time1 label1
lift (([Interval time label0] -> [Interval time label1])
-> T time label0 -> T time label1)
-> ([Interval time label0] -> [Interval time label1])
-> T time label0
-> T time label1
forall a b. (a -> b) -> a -> b
$ (Interval time label0 -> Interval time label1)
-> [Interval time label0] -> [Interval time label1]
forall a b. (a -> b) -> [a] -> [b]
map (\((time, time)
bnd, label0
lab) -> ((time, time)
bnd, (time, time) -> label0 -> label1
f (time, time)
bnd label0
lab))
realTimes ::
(Fractional time) =>
time -> T Int label -> T time label
realTimes :: time -> T Int label -> T time label
realTimes time
sampleRate =
(Int -> time) -> T Int label -> T time label
forall time0 time1 label.
(time0 -> time1) -> T time0 label -> T time1 label
mapTime (\Int
t -> Int -> time
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
t time -> time -> time
forall a. Fractional a => a -> a -> a
/ time
sampleRate)
mask :: (Ord time) => (time, time) -> T time label -> T time label
mask :: (time, time) -> T time label -> T time label
mask (time
from,time
to) =
([Interval time label] -> [Interval time label])
-> T time label -> T time label
forall time0 label0 time1 label1.
([Interval time0 label0] -> [Interval time1 label1])
-> T time0 label0 -> T time1 label1
lift (([Interval time label] -> [Interval time label])
-> T time label -> T time label)
-> ([Interval time label] -> [Interval time label])
-> T time label
-> T time label
forall a b. (a -> b) -> a -> b
$
(Interval time label -> Bool)
-> [Interval time label] -> [Interval time label]
forall a. (a -> Bool) -> [a] -> [a]
filter ((time -> time -> Bool) -> (time, time) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry time -> time -> Bool
forall a. Ord a => a -> a -> Bool
(<) ((time, time) -> Bool)
-> (Interval time label -> (time, time))
-> Interval time label
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval time label -> (time, time)
forall a b. (a, b) -> a
fst) ([Interval time label] -> [Interval time label])
-> ([Interval time label] -> [Interval time label])
-> [Interval time label]
-> [Interval time label]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(Interval time label -> Interval time label)
-> [Interval time label] -> [Interval time label]
forall a b. (a -> b) -> [a] -> [b]
map (((time, time) -> (time, time))
-> Interval time label -> Interval time label
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst ((time -> time, time -> time) -> (time, time) -> (time, time)
forall a c b d. (a -> c, b -> d) -> (a, b) -> (c, d)
mapPair (time -> time -> time
forall a. Ord a => a -> a -> a
max time
from, time -> time -> time
forall a. Ord a => a -> a -> a
min time
to)))
zipWithList ::
(label0 -> label1 -> label2) -> [label0] -> T time label1 -> T time label2
zipWithList :: (label0 -> label1 -> label2)
-> [label0] -> T time label1 -> T time label2
zipWithList label0 -> label1 -> label2
f [label0]
xs = ([Interval time label1] -> [Interval time label2])
-> T time label1 -> T time label2
forall time0 label0 time1 label1.
([Interval time0 label0] -> [Interval time1 label1])
-> T time0 label0 -> T time1 label1
lift (([Interval time label1] -> [Interval time label2])
-> T time label1 -> T time label2)
-> ([Interval time label1] -> [Interval time label2])
-> T time label1
-> T time label2
forall a b. (a -> b) -> a -> b
$ (label0 -> Interval time label1 -> Interval time label2)
-> [label0] -> [Interval time label1] -> [Interval time label2]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\label0
x ((time, time)
bnd, label1
y) -> ((time, time)
bnd, label0 -> label1 -> label2
f label0
x label1
y)) [label0]
xs
writeFile :: (RealFrac time) => FilePath -> T time String -> IO ()
writeFile :: String -> T time String -> IO ()
writeFile String
path T time String
intervals =
String -> String -> IO ()
P.writeFile String
path (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$
((Interval String String -> String)
-> [Interval String String] -> [String])
-> [Interval String String]
-> (Interval String String -> String)
-> [String]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Interval String String -> String)
-> [Interval String String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (T String String -> [Interval String String]
forall time label. T time label -> [Interval time label]
decons (T String String -> [Interval String String])
-> T String String -> [Interval String String]
forall a b. (a -> b) -> a -> b
$ (time -> String) -> T time String -> T String String
forall time0 time1 label.
(time0 -> time1) -> T time0 label -> T time1 label
mapTime time -> String
forall time. RealFrac time => time -> String
formatTime T time String
intervals) ((Interval String String -> String) -> [String])
-> (Interval String String -> String) -> [String]
forall a b. (a -> b) -> a -> b
$ \((String
from,String
to),String
label) ->
String -> String -> String -> ShowS
forall r. PrintfType r => String -> r
printf String
"%s\t%s\t%s" String
from String
to String
label
writeFileInt ::
(RealFrac time) =>
time -> FilePath -> T Int String -> IO ()
writeFileInt :: time -> String -> T Int String -> IO ()
writeFileInt time
sampleRate String
path =
String -> T time String -> IO ()
forall time. RealFrac time => String -> T time String -> IO ()
writeFile String
path (T time String -> IO ())
-> (T Int String -> T time String) -> T Int String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. time -> T Int String -> T time String
forall time label.
Fractional time =>
time -> T Int label -> T time label
realTimes time
sampleRate
parseTime :: (Fractional time) => String -> Maybe time
parseTime :: String -> Maybe time
parseTime String
str =
case (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char
','Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==) String
str of
(String
intStr, Char
',':String
fracStr) -> do
Integer
int <- String -> Maybe Integer
forall a. Read a => String -> Maybe a
maybeRead String
intStr
Integer
frac <- String -> Maybe Integer
forall a. Read a => String -> Maybe a
maybeRead String
fracStr
time -> Maybe time
forall (m :: * -> *) a. Monad m => a -> m a
return (time -> Maybe time) -> time -> Maybe time
forall a b. (a -> b) -> a -> b
$
Integer -> time
forall a. Num a => Integer -> a
fromInteger Integer
int time -> time -> time
forall a. Num a => a -> a -> a
+
Integer -> time
forall a. Num a => Integer -> a
fromInteger Integer
frac time -> time -> time
forall a. Fractional a => a -> a -> a
/ Integer -> time
forall a. Num a => Integer -> a
fromInteger (Integer
10 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
fracStr)
(String
intStr, []) -> (Integer -> time) -> Maybe Integer -> Maybe time
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Integer -> time
forall a. Num a => Integer -> a
fromInteger (Maybe Integer -> Maybe time) -> Maybe Integer -> Maybe time
forall a b. (a -> b) -> a -> b
$ String -> Maybe Integer
forall a. Read a => String -> Maybe a
maybeRead String
intStr
(String
_, Char
_:String
_) -> String -> Maybe time
forall a. HasCallStack => String -> a
error String
"break seems to match other characters than comma"
readFile :: (Fractional time) => FilePath -> IO (T time String)
readFile :: String -> IO (T time String)
readFile String
name =
let parseTimeIO :: t -> String -> IO a
parseTimeIO t
n String
str =
case String -> Maybe a
forall time. Fractional time => String -> Maybe time
parseTime String
str of
Just a
t -> a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
t
Maybe a
Nothing ->
IOError -> IO a
forall a. IOError -> IO a
ioError (IOError -> IO a) -> IOError -> IO a
forall a b. (a -> b) -> a -> b
$ String -> IOError
userError (String -> IOError) -> String -> IOError
forall a b. (a -> b) -> a -> b
$
String -> String -> t -> ShowS
forall r. PrintfType r => String -> r
printf String
"%s:%d: \"%s\" is not a number" String
name t
n String
str
parseLine :: t -> String -> IO ((a, b), String)
parseLine t
n String
ln =
case (Char -> Bool) -> String -> [String]
forall a. (a -> Bool) -> [a] -> [[a]]
ListHT.chop (Char
'\t'Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==) String
ln of
[String
fromStr, String
toStr, String
label] -> do
a
from <- t -> String -> IO a
forall a t. (Fractional a, PrintfArg t) => t -> String -> IO a
parseTimeIO t
n String
fromStr
b
to <- t -> String -> IO b
forall a t. (Fractional a, PrintfArg t) => t -> String -> IO a
parseTimeIO t
n String
toStr
((a, b), String) -> IO ((a, b), String)
forall (m :: * -> *) a. Monad m => a -> m a
return ((a
from, b
to), String
label)
[String]
fields ->
IOError -> IO ((a, b), String)
forall a. IOError -> IO a
ioError (IOError -> IO ((a, b), String)) -> IOError -> IO ((a, b), String)
forall a b. (a -> b) -> a -> b
$ String -> IOError
userError (String -> IOError) -> String -> IOError
forall a b. (a -> b) -> a -> b
$
String -> String -> t -> Int -> String
forall r. PrintfType r => String -> r
printf String
"%s:%d: expected 3 fields, but got %d"
String
name t
n ([String] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
fields)
in ([Interval time String] -> T time String)
-> IO [Interval time String] -> IO (T time String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Interval time String] -> T time String
forall time label. [Interval time label] -> T time label
Cons (IO [Interval time String] -> IO (T time String))
-> IO [Interval time String] -> IO (T time String)
forall a b. (a -> b) -> a -> b
$ (Int -> String -> IO (Interval time String))
-> [Int] -> [String] -> IO [Interval time String]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM Int -> String -> IO (Interval time String)
forall t a b.
(PrintfArg t, Fractional a, Fractional b) =>
t -> String -> IO ((a, b), String)
parseLine [Int
1::Int ..] ([String] -> IO [Interval time String])
-> (String -> [String]) -> String -> IO [Interval time String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines (String -> IO [Interval time String])
-> IO String -> IO [Interval time String]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> IO String
P.readFile String
name