-- | Like '(=~+)', but find all matches, not just the first one.
(=~++) :: Source -> Match -> [[(Source, (MatchOffset, MatchLength))]]
(=~++) source match = case source =~+ match of
                        [] -> []
                        x@((_, (holeStart, holeEnd)):_) -> x : map (shift (holeStart + holeEnd))
                                                                   (LBS.drop (fromIntegral $ holeStart + holeEnd) source =~++ match)
  where
    shift :: Int -> [(Source, (MatchOffset, MatchLength))] -> [(Source, (MatchOffset, MatchLength))]
    shift o' = map (\ (s, (o, l)) -> (s, (o + o', l)))


-- | Replace first match with result of a function of the match.
(=~++) :: Source -> Match -> [[(Source, (MatchOffset, MatchLength))]]
(=~++) source match = case source =~+ match of
                        [] -> []
                        x@((_, (holeStart, holeEnd)):_) -> x : map (shift (holeStart + holeEnd))
                                                                   (LBS.drop (fromIntegral $ holeStart + holeEnd) source =~++ match)
  where
    shift :: Int -> [(Source, (MatchOffset, MatchLength))] -> [(Source, (MatchOffset, MatchLength))]
    shift o' = map (\ (s, (o, l)) -> (s, (o + o', l)))


-- | Replace first match with result of a function of the match.
(=~++) source match = case source =~+ match of
                        [] -> []
                        x@((_, (holeStart, holeEnd)):_) -> x : map (shift (holeStart + holeEnd))
                                                                   (LBS.drop (fromIntegral $ holeStart + holeEnd) source =~++ match)
  where
    shift :: Int -> [(Source, (MatchOffset, MatchLength))] -> [(Source, (MatchOffset, MatchLength))]
    shift o' = map (\ (s, (o, l)) -> (s, (o + o', l)))


-- | Replace first match with result of a function of the match.