    \begin{code}
    {-# LANGUAGE NoImplicitPrelude          #-}
    {-# LANGUAGE QuasiQuotes                #-}
    {-# LANGUAGE OverloadedStrings          #-}
    {-# LANGUAGE RecordWildCards            #-}
    {-# LANGUAGE FlexibleContexts           #-}
    {-# LANGUAGE FlexibleInstances          #-}
    {-# LANGUAGE MonoLocalBinds             #-}

    module Text.RE.ZeInternals.Replace
      (
      -- * REContext and RELocation
        REContext(..)
      , RELocation(..)
      , isTopLocation
      -- * replaceAll
      , replaceAll
      , replaceAllCaptures
      , replaceAllCaptures_
      , replaceAllCapturesM
      -- * replace
      , replace
      , replaceCaptures
      , replaceCaptures_
      , replaceCapturesM
      -- * expandMacros
      , expandMacros
      , expandMacros'
      -- * templateCaptures
      , templateCaptures
      -- * Replace and ReplaceMethods
      , Replace(..)
      , ReplaceMethods(..)
      , replaceMethods
      ) where

    import           Control.Applicative
    import           Data.Array
    import qualified Data.ByteString.Char8          as B
    import qualified Data.ByteString.Lazy.Char8     as LBS
    import           Data.Char
    import qualified Data.Foldable                  as F
    import           Data.Functor.Identity
    import qualified Data.HashMap.Strict            as HM
    import           Data.Maybe
    import qualified Data.Monoid                    as M
    import qualified Data.Sequence                  as S
    import qualified Data.Text                      as T
    import qualified Data.Text.Encoding             as TE
    import qualified Data.Text.Lazy                 as LT
    import           Prelude.Compat
    import           Text.RE.REOptions
    import           Text.RE.ZeInternals.Types.Capture
    import           Text.RE.ZeInternals.Types.CaptureID
    import           Text.RE.ZeInternals.Types.Match
    import           Text.RE.ZeInternals.Types.Matches
    import           Text.Read
    import           Text.Regex.TDFA
    import           Text.Regex.TDFA.Text()
    import           Text.Regex.TDFA.Text.Lazy()
    \end{code}

    ReContext and RELocation
    ------------------------

    \begin{code}
    -- | @REContext@ specifies which contexts the substitutions should be applied
    data REContext
      = TOP   -- ^ substitutions should be applied to the top-level only,
              -- the text that matched the whole RE
      | SUB   -- ^ substitutions should only be applied to the text
              -- captured by bracketed sub-REs
      | ALL   -- ^ the substitution function should be applied to all
              -- captures, the top level and the sub-expression captures
      deriving (Int -> REContext -> ShowS
    [REContext] -> ShowS
    REContext -> [Char]
    (Int -> REContext -> ShowS)
    -> (REContext -> [Char])
    -> ([REContext] -> ShowS)
    -> Show REContext
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> REContext -> ShowS
    showsPrec :: Int -> REContext -> ShowS
    $cshow :: REContext -> [Char]
    show :: REContext -> [Char]
    $cshowList :: [REContext] -> ShowS
    showList :: [REContext] -> ShowS
    Show)

    -- | the @RELocation@ information passed into the substitution function
    -- specifies which sub-expression is being substituted
    data RELocation =
      RELocation
        { RELocation -> Int
    locationMatch   :: Int
              -- ^ the zero-based, i-th string to be matched,
              -- when matching all strings, zero when only the
              -- first string is being matched
        , RELocation -> CaptureOrdinal
    locationCapture :: CaptureOrdinal
              -- ^ 0, when matching the top-level string
              -- matched by the whole RE, 1 for the top-most,
              -- left-most redex captured by bracketed
              -- sub-REs, etc.
        }
      deriving (Int -> RELocation -> ShowS
    [RELocation] -> ShowS
    RELocation -> [Char]
    (Int -> RELocation -> ShowS)
    -> (RELocation -> [Char])
    -> ([RELocation] -> ShowS)
    -> Show RELocation
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> RELocation -> ShowS
    showsPrec :: Int -> RELocation -> ShowS
    $cshow :: RELocation -> [Char]
    show :: RELocation -> [Char]
    $cshowList :: [RELocation] -> ShowS
    showList :: [RELocation] -> ShowS
    Show)
    \end{code}

    \begin{code}
    -- | True iff the location references a complete match
    -- (i.e., not a bracketed capture)
    isTopLocation :: RELocation -> Bool
    isTopLocation :: RELocation -> Bool
    isTopLocation = (CaptureOrdinal -> CaptureOrdinal -> Bool
    forall a. Eq a => a -> a -> Bool
    ==CaptureOrdinal
    0) (CaptureOrdinal -> Bool)
    -> (RELocation -> CaptureOrdinal) -> RELocation -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . RELocation -> CaptureOrdinal
    locationCapture
    \end{code}

    \begin{code}
    -- | replace all with a template, $0 for whole text, $1 for first
    -- capture, etc.
    replaceAll :: Replace a
               => a
               -> Matches a
               -> a
    replaceAll :: forall a. Replace a => a -> Matches a -> a
    replaceAll a
    tpl Matches a
    ac = REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Matches a
    -> a
    forall a.
    Replace a =>
    REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Matches a
    -> a
    replaceAllCaptures REContext
    TOP (a -> Match a -> RELocation -> Capture a -> Maybe a
    forall a.
    Replace a =>
    a -> Match a -> RELocation -> Capture a -> Maybe a
    parseTemplateR a
    tpl) Matches a
    ac
    \end{code}

    \begin{code}
    -- | substitutes using a function that takes the full Match
    -- context and returns the same replacement text as the _phi_phi
    -- context.
    replaceAllCaptures :: Replace a
                       => REContext
                       -> (Match a->RELocation->Capture a->Maybe a)
                       -> Matches a
                       -> a
    \end{code}

    \begin{code}
    replaceAllCaptures :: forall a.
    Replace a =>
    REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Matches a
    -> a
    replaceAllCaptures = ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Matches a
    -> a
    forall a.
    Extract a =>
    ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Matches a
    -> a
    replaceAllCaptures_ ReplaceMethods a
    forall a. Replace a => ReplaceMethods a
    replaceMethods
    \end{code}

    \begin{code}
    -- | replaceAllCaptures_ is like like replaceAllCaptures but takes the
    -- Replace methods through the ReplaceMethods argument
    replaceAllCaptures_ :: Extract a
                        => ReplaceMethods a
                        -> REContext
                        -> (Match a->RELocation->Capture a->Maybe a)
                        -> Matches a
                        -> a
    replaceAllCaptures_ :: forall a.
    Extract a =>
    ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Matches a
    -> a
    replaceAllCaptures_ ReplaceMethods a
    s REContext
    ctx Match a -> RELocation -> Capture a -> Maybe a
    phi Matches a
    ac =
        Identity a -> a
    forall a. Identity a -> a
    runIdentity (Identity a -> a) -> Identity a -> a
    forall a b. (a -> b) -> a -> b
    $ ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> Identity (Maybe a))
    -> Matches a
    -> Identity a
    forall a (m :: * -> *).
    (Extract a, Monad m) =>
    ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> m (Maybe a))
    -> Matches a
    -> m a
    replaceAllCapturesM ReplaceMethods a
    s REContext
    ctx ((Match a -> RELocation -> Capture a -> Maybe a)
    -> Match a -> RELocation -> Capture a -> Identity (Maybe a)
    forall (m :: * -> *) a.
    Monad m =>
    (Match a -> RELocation -> Capture a -> Maybe a)
    -> Match a -> RELocation -> Capture a -> m (Maybe a)
    lift_phi Match a -> RELocation -> Capture a -> Maybe a
    phi) Matches a
    ac
    \end{code}

    \begin{code}
    -- | replaceAllCapturesM is just a monadically generalised version of
    -- replaceAllCaptures_
    replaceAllCapturesM :: (Extract a,Monad m)
                        => ReplaceMethods a
                        -> REContext
                        -> (Match a->RELocation->Capture a->m (Maybe a))
                        -> Matches a
                        -> m a
    replaceAllCapturesM :: forall a (m :: * -> *).
    (Extract a, Monad m) =>
    ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> m (Maybe a))
    -> Matches a
    -> m a
    replaceAllCapturesM ReplaceMethods a
    r REContext
    ctx Match a -> RELocation -> Capture a -> m (Maybe a)
    phi_ Matches{a
    [Match a]
    matchesSource :: a
    allMatches :: [Match a]
    allMatches :: forall a. Matches a -> [Match a]
    matchesSource :: forall a. Matches a -> a
    ..} =
        ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> m (Maybe a))
    -> Match a
    -> m a
    forall (m :: * -> *) a.
    (Monad m, Extract a) =>
    ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> m (Maybe a))
    -> Match a
    -> m a
    replaceCapturesM ReplaceMethods a
    r REContext
    ALL Match a -> RELocation -> Capture a -> m (Maybe a)
    phi (Match a -> m a) -> Match a -> m a
    forall a b. (a -> b) -> a -> b
    $ a -> CaptureNames -> Array CaptureOrdinal (Capture a) -> Match a
    forall a.
    a -> CaptureNames -> Array CaptureOrdinal (Capture a) -> Match a
    Match a
    matchesSource CaptureNames
    cnms Array CaptureOrdinal (Capture a)
    arr
      where
        phi :: Match a -> RELocation -> Capture a -> m (Maybe a)
    phi Match a
    _ (RELocation Int
    _ CaptureOrdinal
    i) = case Array CaptureOrdinal (Maybe (Match a))
    arr_cArray CaptureOrdinal (Maybe (Match a))
    -> CaptureOrdinal -> Maybe (Match a)
    forall i e. Ix i => Array i e -> i -> e
    !CaptureOrdinal
    i of
          Just Match a
    caps -> Match a -> RELocation -> Capture a -> m (Maybe a)
    phi_ Match a
    caps (RELocation -> Capture a -> m (Maybe a))
    -> ((Int, CaptureOrdinal) -> RELocation)
    -> (Int, CaptureOrdinal)
    -> Capture a
    -> m (Maybe a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int -> CaptureOrdinal -> RELocation)
    -> (Int, CaptureOrdinal) -> RELocation
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry Int -> CaptureOrdinal -> RELocation
    RELocation ((Int, CaptureOrdinal) -> Capture a -> m (Maybe a))
    -> (Int, CaptureOrdinal) -> Capture a -> m (Maybe a)
    forall a b. (a -> b) -> a -> b
    $ Array CaptureOrdinal (Int, CaptureOrdinal)
    arr_i Array CaptureOrdinal (Int, CaptureOrdinal)
    -> CaptureOrdinal -> (Int, CaptureOrdinal)
    forall i e. Ix i => Array i e -> i -> e
    ! CaptureOrdinal
    i
          Maybe (Match a)
    Nothing   -> m (Maybe a) -> Capture a -> m (Maybe a)
    forall a b. a -> b -> a
    const (m (Maybe a) -> Capture a -> m (Maybe a))
    -> m (Maybe a) -> Capture a -> m (Maybe a)
    forall a b. (a -> b) -> a -> b
    $ Maybe a -> m (Maybe a)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe a
    forall a. Maybe a
    Nothing

        arr_c :: Array CaptureOrdinal (Maybe (Match a))
    arr_c = (CaptureOrdinal, CaptureOrdinal)
    -> [Maybe (Match a)] -> Array CaptureOrdinal (Maybe (Match a))
    forall i e. Ix i => (i, i) -> [e] -> Array i e
    listArray (CaptureOrdinal, CaptureOrdinal)
    bds ([Maybe (Match a)] -> Array CaptureOrdinal (Maybe (Match a)))
    -> [Maybe (Match a)] -> Array CaptureOrdinal (Maybe (Match a))
    forall a b. (a -> b) -> a -> b
    $
          [[Maybe (Match a)]] -> [Maybe (Match a)]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[Maybe (Match a)]] -> [Maybe (Match a)])
    -> [[Maybe (Match a)]] -> [Maybe (Match a)]
    forall a b. (a -> b) -> a -> b
    $
            [ Int -> Match a -> [Maybe (Match a)]
    repl ((CaptureOrdinal, CaptureOrdinal) -> Int
    forall a. Ix a => (a, a) -> Int
    rangeSize ((CaptureOrdinal, CaptureOrdinal) -> Int)
    -> (CaptureOrdinal, CaptureOrdinal) -> Int
    forall a b. (a -> b) -> a -> b
    $ Array CaptureOrdinal (Capture a)
    -> (CaptureOrdinal, CaptureOrdinal)
    forall i e. Array i e -> (i, i)
    bounds (Array CaptureOrdinal (Capture a)
     -> (CaptureOrdinal, CaptureOrdinal))
    -> Array CaptureOrdinal (Capture a)
    -> (CaptureOrdinal, CaptureOrdinal)
    forall a b. (a -> b) -> a -> b
    $ Match a -> Array CaptureOrdinal (Capture a)
    forall a. Match a -> Array CaptureOrdinal (Capture a)
    matchArray Match a
    cs) Match a
    cs
                | Match a
    cs <- [Match a]
    allMatches
                ]

        arr_i :: Array CaptureOrdinal (Int, CaptureOrdinal)
    arr_i = (CaptureOrdinal, CaptureOrdinal)
    -> [(Int, CaptureOrdinal)]
    -> Array CaptureOrdinal (Int, CaptureOrdinal)
    forall i e. Ix i => (i, i) -> [e] -> Array i e
    listArray (CaptureOrdinal, CaptureOrdinal)
    bds [(Int, CaptureOrdinal)]
    j_ks

        arr :: Array CaptureOrdinal (Capture a)
    arr   = (CaptureOrdinal, CaptureOrdinal)
    -> [Capture a] -> Array CaptureOrdinal (Capture a)
    forall i e. Ix i => (i, i) -> [e] -> Array i e
    listArray (CaptureOrdinal, CaptureOrdinal)
    bds ([Capture a] -> Array CaptureOrdinal (Capture a))
    -> [Capture a] -> Array CaptureOrdinal (Capture a)
    forall a b. (a -> b) -> a -> b
    $
            [ Array CaptureOrdinal (Capture a)
    arr_ Array CaptureOrdinal (Capture a) -> CaptureOrdinal -> Capture a
    forall i e. Ix i => Array i e -> i -> e
    ! CaptureOrdinal
    k
                | Array CaptureOrdinal (Capture a)
    arr_ <- (Match a -> Array CaptureOrdinal (Capture a))
    -> [Match a] -> [Array CaptureOrdinal (Capture a)]
    forall a b. (a -> b) -> [a] -> [b]
    map Match a -> Array CaptureOrdinal (Capture a)
    forall a. Match a -> Array CaptureOrdinal (Capture a)
    matchArray [Match a]
    allMatches
                , CaptureOrdinal
    k    <- Array CaptureOrdinal (Capture a) -> [CaptureOrdinal]
    forall i e. Ix i => Array i e -> [i]
    indices Array CaptureOrdinal (Capture a)
    arr_
                ]

        bds :: (CaptureOrdinal, CaptureOrdinal)
    bds   = (CaptureOrdinal
    0,Int -> CaptureOrdinal
    CaptureOrdinal (Int -> CaptureOrdinal) -> Int -> CaptureOrdinal
    forall a b. (a -> b) -> a -> b
    $ [(Int, CaptureOrdinal)] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [(Int, CaptureOrdinal)]
    j_ksInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1)

        j_ks :: [(Int, CaptureOrdinal)]
    j_ks  =
            [ (Int
    j,CaptureOrdinal
    k)
                | (Int
    j,Array CaptureOrdinal (Capture a)
    arr_) <- [Int]
    -> [Array CaptureOrdinal (Capture a)]
    -> [(Int, Array CaptureOrdinal (Capture a))]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Int
    0..] ([Array CaptureOrdinal (Capture a)]
     -> [(Int, Array CaptureOrdinal (Capture a))])
    -> [Array CaptureOrdinal (Capture a)]
    -> [(Int, Array CaptureOrdinal (Capture a))]
    forall a b. (a -> b) -> a -> b
    $ (Match a -> Array CaptureOrdinal (Capture a))
    -> [Match a] -> [Array CaptureOrdinal (Capture a)]
    forall a b. (a -> b) -> [a] -> [b]
    map Match a -> Array CaptureOrdinal (Capture a)
    forall a. Match a -> Array CaptureOrdinal (Capture a)
    matchArray [Match a]
    allMatches
                ,  CaptureOrdinal
    k       <- Array CaptureOrdinal (Capture a) -> [CaptureOrdinal]
    forall i e. Ix i => Array i e -> [i]
    indices Array CaptureOrdinal (Capture a)
    arr_
                ]

        repl :: Int -> Match a -> [Maybe (Match a)]
    repl Int
    0 Match a
    _ = []
        repl Int
    n Match a
    x = case REContext
    ctx of
          REContext
    TOP -> Match a -> Maybe (Match a)
    forall a. a -> Maybe a
    Just Match a
    x  Maybe (Match a) -> [Maybe (Match a)] -> [Maybe (Match a)]
    forall a. a -> [a] -> [a]
    : Int -> Maybe (Match a) -> [Maybe (Match a)]
    forall a. Int -> a -> [a]
    replicate (Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1) Maybe (Match a)
    forall a. Maybe a
    Nothing
          REContext
    SUB -> Maybe (Match a)
    forall a. Maybe a
    Nothing Maybe (Match a) -> [Maybe (Match a)] -> [Maybe (Match a)]
    forall a. a -> [a] -> [a]
    : Int -> Maybe (Match a) -> [Maybe (Match a)]
    forall a. Int -> a -> [a]
    replicate (Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1) (Match a -> Maybe (Match a)
    forall a. a -> Maybe a
    Just Match a
    x)
          REContext
    ALL -> Int -> Maybe (Match a) -> [Maybe (Match a)]
    forall a. Int -> a -> [a]
    replicate Int
    n (Maybe (Match a) -> [Maybe (Match a)])
    -> Maybe (Match a) -> [Maybe (Match a)]
    forall a b. (a -> b) -> a -> b
    $ Match a -> Maybe (Match a)
    forall a. a -> Maybe a
    Just Match a
    x

        cnms :: CaptureNames
    cnms = CaptureNames -> Maybe CaptureNames -> CaptureNames
    forall a. a -> Maybe a -> a
    fromMaybe CaptureNames
    noCaptureNames (Maybe CaptureNames -> CaptureNames)
    -> Maybe CaptureNames -> CaptureNames
    forall a b. (a -> b) -> a -> b
    $ [CaptureNames] -> Maybe CaptureNames
    forall a. [a] -> Maybe a
    listToMaybe ([CaptureNames] -> Maybe CaptureNames)
    -> [CaptureNames] -> Maybe CaptureNames
    forall a b. (a -> b) -> a -> b
    $ (Match a -> CaptureNames) -> [Match a] -> [CaptureNames]
    forall a b. (a -> b) -> [a] -> [b]
    map Match a -> CaptureNames
    forall a. Match a -> CaptureNames
    captureNames [Match a]
    allMatches
    \end{code}

    \begin{code}
    -- | replace with a template containing $0 for whole text,
    -- $1 for first capture, etc.
    replace :: Replace a
            => a
            -> Match a
            -> a
    replace :: forall a. Replace a => a -> Match a -> a
    replace a
    tpl Match a
    c = REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a) -> Match a -> a
    forall a.
    Replace a =>
    REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a) -> Match a -> a
    replaceCaptures REContext
    TOP (a -> Match a -> RELocation -> Capture a -> Maybe a
    forall a.
    Replace a =>
    a -> Match a -> RELocation -> Capture a -> Maybe a
    parseTemplateR a
    tpl) Match a
    c
    \end{code}

    \begin{code}
    -- | substitutes using a function that takes the full Match
    -- context and returns the same replacement text as the _phi_phi
    -- context.
    replaceCaptures :: Replace a
                     => REContext
                     -> (Match a->RELocation->Capture a->Maybe a)
                     -> Match a
                     -> a
    replaceCaptures :: forall a.
    Replace a =>
    REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a) -> Match a -> a
    replaceCaptures = ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Match a
    -> a
    forall a.
    Extract a =>
    ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Match a
    -> a
    replaceCaptures_ ReplaceMethods a
    forall a. Replace a => ReplaceMethods a
    replaceMethods
    \end{code}

    \begin{code}
    -- | replaceCaptures_ is like replaceCaptures but takes the Replace methods
    -- through the ReplaceMethods argument
    replaceCaptures_ :: Extract a
                     => ReplaceMethods a
                     -> REContext
                     -> (Match a->RELocation->Capture a->Maybe a)
                     -> Match a
                     -> a
    replaceCaptures_ :: forall a.
    Extract a =>
    ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Match a
    -> a
    replaceCaptures_ ReplaceMethods a
    s REContext
    ctx Match a -> RELocation -> Capture a -> Maybe a
    phi Match a
    caps =
      Identity a -> a
    forall a. Identity a -> a
    runIdentity (Identity a -> a) -> Identity a -> a
    forall a b. (a -> b) -> a -> b
    $ ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> Identity (Maybe a))
    -> Match a
    -> Identity a
    forall (m :: * -> *) a.
    (Monad m, Extract a) =>
    ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> m (Maybe a))
    -> Match a
    -> m a
    replaceCapturesM ReplaceMethods a
    s REContext
    ctx ((Match a -> RELocation -> Capture a -> Maybe a)
    -> Match a -> RELocation -> Capture a -> Identity (Maybe a)
    forall (m :: * -> *) a.
    Monad m =>
    (Match a -> RELocation -> Capture a -> Maybe a)
    -> Match a -> RELocation -> Capture a -> m (Maybe a)
    lift_phi Match a -> RELocation -> Capture a -> Maybe a
    phi) Match a
    caps
    \end{code}

    \begin{code}
    -- | replaceCapturesM is just a monadically generalised version of
    -- replaceCaptures_
    replaceCapturesM :: (Monad m,Extract a)
                     => ReplaceMethods a
                     -> REContext
                     -> (Match a->RELocation->Capture a->m (Maybe a))
                     -> Match a
                     -> m a
    replaceCapturesM :: forall (m :: * -> *) a.
    (Monad m, Extract a) =>
    ReplaceMethods a
    -> REContext
    -> (Match a -> RELocation -> Capture a -> m (Maybe a))
    -> Match a
    -> m a
    replaceCapturesM ReplaceMethods{a -> Int
    (a -> a) -> Capture a -> a
    methodLength :: a -> Int
    methodSubst :: (a -> a) -> Capture a -> a
    methodSubst :: forall a. ReplaceMethods a -> (a -> a) -> Capture a -> a
    methodLength :: forall a. ReplaceMethods a -> a -> Int
    ..} REContext
    ctx Match a -> RELocation -> Capture a -> m (Maybe a)
    phi_ caps :: Match a
    caps@Match{a
    Array CaptureOrdinal (Capture a)
    CaptureNames
    matchArray :: forall a. Match a -> Array CaptureOrdinal (Capture a)
    captureNames :: forall a. Match a -> CaptureNames
    matchSource :: a
    captureNames :: CaptureNames
    matchArray :: Array CaptureOrdinal (Capture a)
    matchSource :: forall a. Match a -> a
    ..} = do
        (hay',_) <- ((CaptureOrdinal, Capture a)
     -> m (a, [(Int, Int)]) -> m (a, [(Int, Int)]))
    -> m (a, [(Int, Int)])
    -> [(CaptureOrdinal, Capture a)]
    -> m (a, [(Int, Int)])
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (CaptureOrdinal, Capture a)
    -> m (a, [(Int, Int)]) -> m (a, [(Int, Int)])
    sc ((a, [(Int, Int)]) -> m (a, [(Int, Int)])
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a
    matchSource,[])) ([(CaptureOrdinal, Capture a)] -> m (a, [(Int, Int)]))
    -> [(CaptureOrdinal, Capture a)] -> m (a, [(Int, Int)])
    forall a b. (a -> b) -> a -> b
    $
                        [CaptureOrdinal] -> [Capture a] -> [(CaptureOrdinal, Capture a)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [CaptureOrdinal
    0..] ([Capture a] -> [(CaptureOrdinal, Capture a)])
    -> [Capture a] -> [(CaptureOrdinal, Capture a)]
    forall a b. (a -> b) -> a -> b
    $ Array CaptureOrdinal (Capture a) -> [Capture a]
    forall i e. Array i e -> [e]
    elems Array CaptureOrdinal (Capture a)
    matchArray
        return hay'
      where
        sc :: (CaptureOrdinal, Capture a)
    -> m (a, [(Int, Int)]) -> m (a, [(Int, Int)])
    sc (CaptureOrdinal
    i,Capture a
    cap0) m (a, [(Int, Int)])
    act = do
          (hay,ds) <- m (a, [(Int, Int)])
    act
          let ndl  = Capture a -> a
    forall a. Capture a -> a
    capturedText Capture a
    cap
              cap  = a -> [(Int, Int)] -> Capture a -> Capture a
    forall {a} {a}.
    Extract a =>
    a -> [(Int, Int)] -> Capture a -> Capture a
    adj a
    hay [(Int, Int)]
    ds Capture a
    cap0
          mb <- phi i cap
          case mb of
            Maybe a
    Nothing   -> (a, [(Int, Int)]) -> m (a, [(Int, Int)])
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a
    hay,[(Int, Int)]
    ds)
            Just a
    ndl' ->
                (a, [(Int, Int)]) -> m (a, [(Int, Int)])
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return
                  ( (a -> a) -> Capture a -> a
    methodSubst (a -> a -> a
    forall a b. a -> b -> a
    const a
    ndl') Capture a
    cap
                  , (Capture a -> Int
    forall a. Capture a -> Int
    captureOffset Capture a
    cap,Int
    len'Int -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    len) (Int, Int) -> [(Int, Int)] -> [(Int, Int)]
    forall a. a -> [a] -> [a]
    : [(Int, Int)]
    ds
                  )
              where
                len' :: Int
    len' = a -> Int
    methodLength a
    ndl'
                len :: Int
    len  = a -> Int
    methodLength a
    ndl

        adj :: a -> [(Int, Int)] -> Capture a -> Capture a
    adj a
    hay [(Int, Int)]
    ds Capture a
    cap =
          Capture
            { captureSource :: a
    captureSource = a
    hay
            , capturedText :: a
    capturedText  = Int -> a -> a
    forall source. Extract source => Int -> source -> source
    before Int
    len (a -> a) -> a -> a
    forall a b. (a -> b) -> a -> b
    $ Int -> a -> a
    forall source. Extract source => Int -> source -> source
    after Int
    off0 a
    hay
            , captureOffset :: Int
    captureOffset = Int
    off0
            , captureLength :: Int
    captureLength = Int
    len
            }
          where
            len :: Int
    len  = Int
    len0 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + [Int] -> Int
    forall a. Num a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum
              [ Int
    delta
                | (Int
    off,Int
    delta) <- [(Int, Int)]
    ds
                , Int
    off Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    off0 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    len0
                ]
            len0 :: Int
    len0 = Capture a -> Int
    forall a. Capture a -> Int
    captureLength Capture a
    cap
            off0 :: Int
    off0 = Capture a -> Int
    forall a. Capture a -> Int
    captureOffset Capture a
    cap

        phi :: CaptureOrdinal -> Capture a -> m (Maybe a)
    phi CaptureOrdinal
    i Capture a
    cap = case REContext
    ctx of
          REContext
    TOP | CaptureOrdinal
    iCaptureOrdinal -> CaptureOrdinal -> Bool
    forall a. Eq a => a -> a -> Bool
    /=CaptureOrdinal
    0 -> Maybe a -> m (Maybe a)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe a
    forall a. Maybe a
    Nothing
          REContext
    SUB | CaptureOrdinal
    iCaptureOrdinal -> CaptureOrdinal -> Bool
    forall a. Eq a => a -> a -> Bool
    ==CaptureOrdinal
    0 ->Maybe a -> m (Maybe a)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return  Maybe a
    forall a. Maybe a
    Nothing
          REContext
    _          ->
            case Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ Capture a -> Bool
    forall a. Capture a -> Bool
    hasCaptured Capture a
    cap of
              Bool
    True  -> Maybe a -> m (Maybe a)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe a
    forall a. Maybe a
    Nothing
              Bool
    False -> Match a -> RELocation -> Capture a -> m (Maybe a)
    phi_ Match a
    caps (Int -> CaptureOrdinal -> RELocation
    RELocation Int
    0 CaptureOrdinal
    i) Capture a
    cap
    \end{code}

    expandMacros
    ------------

    \begin{code}
    -- | expand all of the @{..} macros in the RE in the argument String
    -- according to the Macros argument, preprocessing the RE String
    -- according to the Mode argument (used internally)
    expandMacros :: (r->String) -> Macros r -> String -> String
    expandMacros :: forall r. (r -> [Char]) -> Macros r -> ShowS
    expandMacros r -> [Char]
    x_src Macros r
    hm [Char]
    s =
      case Macros r -> Bool
    forall k v. HashMap k v -> Bool
    HM.null Macros r
    hm of
        Bool
    True  -> [Char]
    s
        Bool
    False -> (MacroID -> Maybe [Char]) -> ShowS
    expandMacros' ((r -> [Char]) -> Maybe r -> Maybe [Char]
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap r -> [Char]
    x_src (Maybe r -> Maybe [Char])
    -> (MacroID -> Maybe r) -> MacroID -> Maybe [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (MacroID -> Macros r -> Maybe r) -> Macros r -> MacroID -> Maybe r
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip MacroID -> Macros r -> Maybe r
    forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
    HM.lookup Macros r
    hm) [Char]
    s
    \end{code}

    \begin{code}
    -- | expand the @{..} macros in the argument string using the given
    -- function
    expandMacros' :: (MacroID->Maybe String) -> String -> String
    expandMacros' :: (MacroID -> Maybe [Char]) -> ShowS
    expandMacros' MacroID -> Maybe [Char]
    lu = ShowS -> ShowS
    forall a. Eq a => (a -> a) -> a -> a
    fixpoint ShowS
    e_m
      where
        e_m :: ShowS
    e_m [Char]
    re_s = REContext
    -> (Match [Char] -> RELocation -> Capture [Char] -> Maybe [Char])
    -> Matches [Char]
    -> [Char]
    forall a.
    Replace a =>
    REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Matches a
    -> a
    replaceAllCaptures REContext
    TOP Match [Char] -> RELocation -> Capture [Char] -> Maybe [Char]
    phi (Matches [Char] -> [Char]) -> Matches [Char] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char]
    re_s [Char] -> [Char] -> Matches [Char]
    forall source target.
    (RegexContext Regex source target,
     RegexMaker Regex CompOption ExecOption [Char]) =>
    source -> [Char] -> target
    $=~ [Char]
    "@(@|\\{([^{}]+)\\})"
          where
            phi :: Match [Char] -> RELocation -> Capture [Char] -> Maybe [Char]
    phi Match [Char]
    mtch RELocation
    _ Capture [Char]
    cap = case [Char]
    txt [Char] -> [Char] -> Bool
    forall a. Eq a => a -> a -> Bool
    == [Char]
    "@@" of
                Bool
    True  -> [Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just   [Char]
    "@"
                Bool
    False -> [Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just ([Char] -> Maybe [Char]) -> [Char] -> Maybe [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> Maybe [Char] -> [Char]
    forall a. a -> Maybe a -> a
    fromMaybe [Char]
    txt (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ MacroID -> Maybe [Char]
    lu MacroID
    ide
              where
                txt :: [Char]
    txt = Capture [Char] -> [Char]
    forall a. Capture a -> a
    capturedText Capture [Char]
    cap
                ide :: MacroID
    ide = [Char] -> MacroID
    MacroID ([Char] -> MacroID) -> [Char] -> MacroID
    forall a b. (a -> b) -> a -> b
    $ Capture [Char] -> [Char]
    forall a. Capture a -> a
    capturedText (Capture [Char] -> [Char]) -> Capture [Char] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ CaptureID -> Match [Char] -> Capture [Char]
    forall a. CaptureID -> Match a -> Capture a
    capture CaptureID
    c2 Match [Char]
    mtch
                c2 :: CaptureID
    c2  = CaptureOrdinal -> CaptureID
    IsCaptureOrdinal (CaptureOrdinal -> CaptureID) -> CaptureOrdinal -> CaptureID
    forall a b. (a -> b) -> a -> b
    $ Int -> CaptureOrdinal
    CaptureOrdinal Int
    2
    \end{code}

    \begin{code}
    lift_phi :: Monad m
             => (Match a->RELocation->Capture a->Maybe a)
             -> (Match a->RELocation->Capture a->m (Maybe a))
    lift_phi :: forall (m :: * -> *) a.
    Monad m =>
    (Match a -> RELocation -> Capture a -> Maybe a)
    -> Match a -> RELocation -> Capture a -> m (Maybe a)
    lift_phi Match a -> RELocation -> Capture a -> Maybe a
    phi_ = Match a -> RELocation -> Capture a -> m (Maybe a)
    phi
      where
        phi :: Match a -> RELocation -> Capture a -> m (Maybe a)
    phi Match a
    caps' RELocation
    loc' Capture a
    cap' = Maybe a -> m (Maybe a)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe a -> m (Maybe a)) -> Maybe a -> m (Maybe a)
    forall a b. (a -> b) -> a -> b
    $ Match a -> RELocation -> Capture a -> Maybe a
    phi_ Match a
    caps' RELocation
    loc' Capture a
    cap'
    \end{code}

    templateCaptures
    ----------------

    \begin{code}
    -- | list all of the CaptureID references in the replace template in
    -- the second argument
    templateCaptures :: ( Replace a
                        , RegexContext Regex a (Matches a)
                        , RegexMaker   Regex CompOption ExecOption String
                        )
                     => (a->String)
                     -> a
                     -> [CaptureID]
    templateCaptures :: forall a.
    (Replace a, RegexContext Regex a (Matches a),
     RegexMaker Regex CompOption ExecOption [Char]) =>
    (a -> [Char]) -> a -> [CaptureID]
    templateCaptures a -> [Char]
    unpack a
    tpl =
        [ CaptureID
    cid
          | Match a
    mtch <- Matches a -> [Match a]
    forall a. Matches a -> [Match a]
    allMatches (Matches a -> [Match a]) -> Matches a -> [Match a]
    forall a b. (a -> b) -> a -> b
    $ a -> Matches a
    forall a.
    (Replace a, RegexContext Regex a (Matches a),
     RegexMaker Regex CompOption ExecOption [Char]) =>
    a -> Matches a
    scan_template a
    tpl
          , Right CaptureID
    cid <- [(a -> [Char]) -> Match a -> Either a CaptureID
    forall a. (a -> [Char]) -> Match a -> Either a CaptureID
    parse_template_capture a -> [Char]
    unpack Match a
    mtch]
          ]

    -- | parse a Match generated by acan_template, returning @Left "$")
    -- iff the capture reference is an escaped @$@ (i.e., @$$@)
    parse_template_capture :: (a->String) -> Match a -> Either a CaptureID
    parse_template_capture :: forall a. (a -> [Char]) -> Match a -> Either a CaptureID
    parse_template_capture a -> [Char]
    unpack Match a
    t_mtch = case Match a
    t_mtch Match a -> CaptureID -> Maybe (Capture a)
    forall a. Match a -> CaptureID -> Maybe (Capture a)
    !$? CaptureID
    c2 of
      Just Capture a
    cap -> case [Char] -> Maybe Int
    forall a. Read a => [Char] -> Maybe a
    readMaybe [Char]
    stg of
          Maybe Int
    Nothing -> CaptureID -> Either a CaptureID
    forall a b. b -> Either a b
    Right (CaptureID -> Either a CaptureID)
    -> CaptureID -> Either a CaptureID
    forall a b. (a -> b) -> a -> b
    $ CaptureName -> CaptureID
    IsCaptureName    (CaptureName -> CaptureID) -> CaptureName -> CaptureID
    forall a b. (a -> b) -> a -> b
    $ Text -> CaptureName
    CaptureName (Text -> CaptureName) -> Text -> CaptureName
    forall a b. (a -> b) -> a -> b
    $ [Char] -> Text
    T.pack [Char]
    stg
          Just Int
    cn -> CaptureID -> Either a CaptureID
    forall a b. b -> Either a b
    Right (CaptureID -> Either a CaptureID)
    -> CaptureID -> Either a CaptureID
    forall a b. (a -> b) -> a -> b
    $ CaptureOrdinal -> CaptureID
    IsCaptureOrdinal (CaptureOrdinal -> CaptureID) -> CaptureOrdinal -> CaptureID
    forall a b. (a -> b) -> a -> b
    $ Int -> CaptureOrdinal
    CaptureOrdinal Int
    cn
        where
          stg :: [Char]
    stg = a -> [Char]
    unpack (a -> [Char]) -> a -> [Char]
    forall a b. (a -> b) -> a -> b
    $ Capture a -> a
    forall a. Capture a -> a
    capturedText Capture a
    cap
      Maybe (Capture a)
    Nothing -> case [Char]
    s [Char] -> [Char] -> Bool
    forall a. Eq a => a -> a -> Bool
    == [Char]
    "$" of
        Bool
    True  -> a -> Either a CaptureID
    forall a b. a -> Either a b
    Left a
    t
        Bool
    False -> CaptureID -> Either a CaptureID
    forall a b. b -> Either a b
    Right (CaptureID -> Either a CaptureID)
    -> CaptureID -> Either a CaptureID
    forall a b. (a -> b) -> a -> b
    $ CaptureOrdinal -> CaptureID
    IsCaptureOrdinal (CaptureOrdinal -> CaptureID) -> CaptureOrdinal -> CaptureID
    forall a b. (a -> b) -> a -> b
    $ Int -> CaptureOrdinal
    CaptureOrdinal (Int -> CaptureOrdinal) -> Int -> CaptureOrdinal
    forall a b. (a -> b) -> a -> b
    $ [Char] -> Int
    forall a. Read a => [Char] -> a
    read [Char]
    s
      where
        s :: [Char]
    s = a -> [Char]
    unpack a
    t
        t :: a
    t = Capture a -> a
    forall a. Capture a -> a
    capturedText (Capture a -> a) -> Capture a -> a
    forall a b. (a -> b) -> a -> b
    $ CaptureID -> Match a -> Capture a
    forall a. CaptureID -> Match a -> Capture a
    capture CaptureID
    c1 Match a
    t_mtch

        c1 :: CaptureID
    c1 = CaptureOrdinal -> CaptureID
    IsCaptureOrdinal (CaptureOrdinal -> CaptureID) -> CaptureOrdinal -> CaptureID
    forall a b. (a -> b) -> a -> b
    $ Int -> CaptureOrdinal
    CaptureOrdinal Int
    1
        c2 :: CaptureID
    c2 = CaptureOrdinal -> CaptureID
    IsCaptureOrdinal (CaptureOrdinal -> CaptureID) -> CaptureOrdinal -> CaptureID
    forall a b. (a -> b) -> a -> b
    $ Int -> CaptureOrdinal
    CaptureOrdinal Int
    2

    -- | scan a replacement template, returning a Match for each capture
    -- reference in the template (like $1, ${foo})
    scan_template :: ( Replace a
                     , RegexContext Regex a (Matches a)
                     , RegexMaker   Regex CompOption ExecOption String
                     )
                  => a
                  -> Matches a
    scan_template :: forall a.
    (Replace a, RegexContext Regex a (Matches a),
     RegexMaker Regex CompOption ExecOption [Char]) =>
    a -> Matches a
    scan_template a
    tpl = a
    tpl a -> [Char] -> Matches a
    forall source target.
    (RegexContext Regex source target,
     RegexMaker Regex CompOption ExecOption [Char]) =>
    source -> [Char] -> target
    $=~ [Char]
    "\\$(\\$|[0-9]|\\{([^{}]+)\\})"
    \end{code}

    Replace and ReplaceMethods
    --------------------------

    \begin{code}
    -- | Replace provides the missing needed to replace the matched
    -- text in a @Replace a => Match a@.
    class (Show a,Eq a,Ord a,Extract a,Monoid a) => Replace a where
      -- | length function for a
      lengthR        :: a -> Int
      -- | inject String into a
      packR          :: String -> a
      -- | project a onto a String
      unpackR        :: a -> String
      -- | inject into Text
      textifyR       :: a -> T.Text
      -- | project Text onto a
      detextifyR     :: T.Text -> a
      -- | split into lines
      linesR         :: a -> [a]
      -- | concatenate a list of lines
      unlinesR       :: [a] -> a
      -- | append a newline
      appendNewlineR :: a -> a
      -- | apply a substitution function to a Capture
      substR         :: (a->a) -> Capture a -> a
      -- | convert a template containing $0, $1, etc., in the first
      -- argument, into a 'phi' replacement function for use with
      -- replaceAllCaptures and replaceCaptures
      parseTemplateR :: a -> Match a -> RELocation -> Capture a -> Maybe a

      textifyR       = [Char] -> Text
    T.pack ([Char] -> Text) -> (a -> [Char]) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> [Char]
    forall a. Replace a => a -> [Char]
    unpackR
      detextifyR     = [Char] -> a
    forall a. Replace a => [Char] -> a
    packR  ([Char] -> a) -> (Text -> [Char]) -> Text -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> [Char]
    T.unpack
      appendNewlineR = (a -> a -> a
    forall a. Semigroup a => a -> a -> a
    M.<> [Char] -> a
    forall a. Replace a => [Char] -> a
    packR [Char]
    "\n")

      substR a -> a
    f m :: Capture a
    m@Capture{a
    Int
    capturedText :: forall a. Capture a -> a
    captureOffset :: forall a. Capture a -> Int
    captureSource :: forall a. Capture a -> a
    captureLength :: forall a. Capture a -> Int
    captureSource :: a
    capturedText :: a
    captureOffset :: Int
    captureLength :: Int
    ..} =
        Capture a -> a
    forall a. Extract a => Capture a -> a
    capturePrefix Capture a
    m a -> a -> a
    forall a. Semigroup a => a -> a -> a
    M.<> a -> a
    f a
    capturedText a -> a -> a
    forall a. Semigroup a => a -> a -> a
    M.<> Capture a -> a
    forall a. Extract a => Capture a -> a
    captureSuffix Capture a
    m
    \end{code}

    \begin{code}
    -- | a selection of the Replace methods can be encapsulated with ReplaceMethods
    -- for the higher-order replacement functions
    data ReplaceMethods a =
      ReplaceMethods
        { forall a. ReplaceMethods a -> a -> Int
    methodLength :: a -> Int
        , forall a. ReplaceMethods a -> (a -> a) -> Capture a -> a
    methodSubst  :: (a->a) -> Capture a -> a
        }

    -- | replaceMethods encapsulates ReplaceMethods a from a Replace a context
    replaceMethods :: Replace a => ReplaceMethods a
    replaceMethods :: forall a. Replace a => ReplaceMethods a
    replaceMethods =
      ReplaceMethods
        { methodLength :: a -> Int
    methodLength = a -> Int
    forall a. Replace a => a -> Int
    lengthR
        , methodSubst :: (a -> a) -> Capture a -> a
    methodSubst  = (a -> a) -> Capture a -> a
    forall a. Replace a => (a -> a) -> Capture a -> a
    substR
        }
    \end{code}

    The Replace Instances
    ---------------------

    \begin{code}
    instance Replace [Char] where
      lengthR :: [Char] -> Int
    lengthR         = [Char] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length
      packR :: ShowS
    packR           = ShowS
    forall a. a -> a
    id
      unpackR :: ShowS
    unpackR         = ShowS
    forall a. a -> a
    id
      textifyR :: [Char] -> Text
    textifyR        = [Char] -> Text
    T.pack
      detextifyR :: Text -> [Char]
    detextifyR      = Text -> [Char]
    T.unpack
      linesR :: [Char] -> [[Char]]
    linesR          = [Char] -> [[Char]]
    lines
      unlinesR :: [[Char]] -> [Char]
    unlinesR        = [[Char]] -> [Char]
    unlines
      appendNewlineR :: ShowS
    appendNewlineR  = ([Char] -> ShowS
    forall a. Semigroup a => a -> a -> a
    M.<>[Char]
    "\n")
      parseTemplateR :: [Char]
    -> Match [Char] -> RELocation -> Capture [Char] -> Maybe [Char]
    parseTemplateR  = ShowS
    -> [Char]
    -> Match [Char]
    -> RELocation
    -> Capture [Char]
    -> Maybe [Char]
    forall a.
    (Replace a, RegexContext Regex a (Matches a),
     RegexMaker Regex CompOption ExecOption [Char]) =>
    (a -> [Char]) -> a -> Match a -> RELocation -> Capture a -> Maybe a
    parseTemplateR' ShowS
    forall a. a -> a
    id

    instance Replace B.ByteString where
      lengthR :: ByteString -> Int
    lengthR         = ByteString -> Int
    B.length
      packR :: [Char] -> ByteString
    packR           = [Char] -> ByteString
    B.pack
      unpackR :: ByteString -> [Char]
    unpackR         = ByteString -> [Char]
    B.unpack
      textifyR :: ByteString -> Text
    textifyR        = ByteString -> Text
    TE.decodeUtf8
      detextifyR :: Text -> ByteString
    detextifyR      = Text -> ByteString
    TE.encodeUtf8
      linesR :: ByteString -> [ByteString]
    linesR          = ByteString -> [ByteString]
    B.lines
      unlinesR :: [ByteString] -> ByteString
    unlinesR        = [ByteString] -> ByteString
    B.unlines
      appendNewlineR :: ByteString -> ByteString
    appendNewlineR  = (ByteString -> ByteString -> ByteString
    forall a. Semigroup a => a -> a -> a
    M.<>ByteString
    "\n")
      parseTemplateR :: ByteString
    -> Match ByteString
    -> RELocation
    -> Capture ByteString
    -> Maybe ByteString
    parseTemplateR  = (ByteString -> [Char])
    -> ByteString
    -> Match ByteString
    -> RELocation
    -> Capture ByteString
    -> Maybe ByteString
    forall a.
    (Replace a, RegexContext Regex a (Matches a),
     RegexMaker Regex CompOption ExecOption [Char]) =>
    (a -> [Char]) -> a -> Match a -> RELocation -> Capture a -> Maybe a
    parseTemplateR' ByteString -> [Char]
    B.unpack

    instance Replace LBS.ByteString where
      lengthR :: ByteString -> Int
    lengthR         = Int64 -> Int
    forall a. Enum a => a -> Int
    fromEnum (Int64 -> Int) -> (ByteString -> Int64) -> ByteString -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> Int64
    LBS.length
      packR :: [Char] -> ByteString
    packR           = [Char] -> ByteString
    LBS.pack
      unpackR :: ByteString -> [Char]
    unpackR         = ByteString -> [Char]
    LBS.unpack
      textifyR :: ByteString -> Text
    textifyR        = ByteString -> Text
    TE.decodeUtf8  (ByteString -> Text)
    -> (ByteString -> ByteString) -> ByteString -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> ByteString
    LBS.toStrict
      linesR :: ByteString -> [ByteString]
    linesR          = ByteString -> [ByteString]
    LBS.lines
      unlinesR :: [ByteString] -> ByteString
    unlinesR        = [ByteString] -> ByteString
    LBS.unlines
      detextifyR :: Text -> ByteString
    detextifyR      = ByteString -> ByteString
    LBS.fromStrict (ByteString -> ByteString)
    -> (Text -> ByteString) -> Text -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> ByteString
    TE.encodeUtf8
      appendNewlineR :: ByteString -> ByteString
    appendNewlineR  = (ByteString -> ByteString -> ByteString
    forall a. Semigroup a => a -> a -> a
    M.<>ByteString
    "\n")
      parseTemplateR :: ByteString
    -> Match ByteString
    -> RELocation
    -> Capture ByteString
    -> Maybe ByteString
    parseTemplateR  = (ByteString -> [Char])
    -> ByteString
    -> Match ByteString
    -> RELocation
    -> Capture ByteString
    -> Maybe ByteString
    forall a.
    (Replace a, RegexContext Regex a (Matches a),
     RegexMaker Regex CompOption ExecOption [Char]) =>
    (a -> [Char]) -> a -> Match a -> RELocation -> Capture a -> Maybe a
    parseTemplateR' ByteString -> [Char]
    LBS.unpack

    instance Replace (S.Seq Char) where
      lengthR :: Seq Char -> Int
    lengthR         = Seq Char -> Int
    forall a. Seq a -> Int
    S.length
      packR :: [Char] -> Seq Char
    packR           = [Char] -> Seq Char
    forall a. [a] -> Seq a
    S.fromList
      unpackR :: Seq Char -> [Char]
    unpackR         = Seq Char -> [Char]
    forall a. Seq a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    F.toList
      linesR :: Seq Char -> [Seq Char]
    linesR          = ([Char] -> Seq Char) -> [[Char]] -> [Seq Char]
    forall a b. (a -> b) -> [a] -> [b]
    map [Char] -> Seq Char
    forall a. Replace a => [Char] -> a
    packR ([[Char]] -> [Seq Char])
    -> (Seq Char -> [[Char]]) -> Seq Char -> [Seq Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> [[Char]]
    lines ([Char] -> [[Char]])
    -> (Seq Char -> [Char]) -> Seq Char -> [[Char]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Seq Char -> [Char]
    forall a. Replace a => a -> [Char]
    unpackR
      unlinesR :: [Seq Char] -> Seq Char
    unlinesR        = [Char] -> Seq Char
    forall a. Replace a => [Char] -> a
    packR ([Char] -> Seq Char)
    -> ([Seq Char] -> [Char]) -> [Seq Char] -> Seq Char
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[Char]] -> [Char]
    unlines ([[Char]] -> [Char])
    -> ([Seq Char] -> [[Char]]) -> [Seq Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Seq Char -> [Char]) -> [Seq Char] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map Seq Char -> [Char]
    forall a. Replace a => a -> [Char]
    unpackR
      parseTemplateR :: Seq Char
    -> Match (Seq Char)
    -> RELocation
    -> Capture (Seq Char)
    -> Maybe (Seq Char)
    parseTemplateR  = (Seq Char -> [Char])
    -> Seq Char
    -> Match (Seq Char)
    -> RELocation
    -> Capture (Seq Char)
    -> Maybe (Seq Char)
    forall a.
    (Replace a, RegexContext Regex a (Matches a),
     RegexMaker Regex CompOption ExecOption [Char]) =>
    (a -> [Char]) -> a -> Match a -> RELocation -> Capture a -> Maybe a
    parseTemplateR' Seq Char -> [Char]
    forall a. Seq a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    F.toList

    instance Replace T.Text where
      lengthR :: Text -> Int
    lengthR         = Text -> Int
    T.length
      packR :: [Char] -> Text
    packR           = [Char] -> Text
    T.pack
      unpackR :: Text -> [Char]
    unpackR         = Text -> [Char]
    T.unpack
      textifyR :: Text -> Text
    textifyR        = Text -> Text
    forall a. a -> a
    id
      detextifyR :: Text -> Text
    detextifyR      = Text -> Text
    forall a. a -> a
    id
      linesR :: Text -> [Text]
    linesR          = Text -> [Text]
    T.lines
      unlinesR :: [Text] -> Text
    unlinesR        = [Text] -> Text
    T.unlines
      appendNewlineR :: Text -> Text
    appendNewlineR  = (Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    M.<>Text
    "\n")
      parseTemplateR :: Text -> Match Text -> RELocation -> Capture Text -> Maybe Text
    parseTemplateR  = (Text -> [Char])
    -> Text -> Match Text -> RELocation -> Capture Text -> Maybe Text
    forall a.
    (Replace a, RegexContext Regex a (Matches a),
     RegexMaker Regex CompOption ExecOption [Char]) =>
    (a -> [Char]) -> a -> Match a -> RELocation -> Capture a -> Maybe a
    parseTemplateR' Text -> [Char]
    T.unpack

    instance Replace LT.Text where
      lengthR :: Text -> Int
    lengthR         = Int64 -> Int
    forall a. Enum a => a -> Int
    fromEnum (Int64 -> Int) -> (Text -> Int64) -> Text -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Int64
    LT.length
      packR :: [Char] -> Text
    packR           = [Char] -> Text
    LT.pack
      unpackR :: Text -> [Char]
    unpackR         = Text -> [Char]
    LT.unpack
      textifyR :: Text -> Text
    textifyR        = Text -> Text
    LT.toStrict
      detextifyR :: Text -> Text
    detextifyR      = Text -> Text
    LT.fromStrict
      linesR :: Text -> [Text]
    linesR          = Text -> [Text]
    LT.lines
      unlinesR :: [Text] -> Text
    unlinesR        = [Text] -> Text
    LT.unlines
      appendNewlineR :: Text -> Text
    appendNewlineR  = (Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    M.<>Text
    "\n")
      parseTemplateR :: Text -> Match Text -> RELocation -> Capture Text -> Maybe Text
    parseTemplateR  = (Text -> [Char])
    -> Text -> Match Text -> RELocation -> Capture Text -> Maybe Text
    forall a.
    (Replace a, RegexContext Regex a (Matches a),
     RegexMaker Regex CompOption ExecOption [Char]) =>
    (a -> [Char]) -> a -> Match a -> RELocation -> Capture a -> Maybe a
    parseTemplateR' Text -> [Char]
    LT.unpack
    \end{code}

    Parsing Replace Templates
    -------------------------

    \begin{code}
    -- | parse the replacement template in second argument, substituting
    -- the capture references with corresponding captures from the Match
    -- in the third argument (the result of a single match of the RE
    -- against the input text to be matched); Nothing is returned if the
    -- inputs are not well formed (currently all inputs are well formed)
    parseTemplateR' :: ( Replace a
                       , RegexContext Regex a (Matches a)
                       , RegexMaker   Regex CompOption ExecOption String
                       )
                       => (a->String)
                       -> a
                       -> Match a
                       -> RELocation
                       -> Capture a
                       -> Maybe a
    parseTemplateR' :: forall a.
    (Replace a, RegexContext Regex a (Matches a),
     RegexMaker Regex CompOption ExecOption [Char]) =>
    (a -> [Char]) -> a -> Match a -> RELocation -> Capture a -> Maybe a
    parseTemplateR' a -> [Char]
    unpack a
    tpl Match a
    mtch RELocation
    _ Capture a
    _ =
        a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Matches a
    -> a
    forall a.
    Replace a =>
    REContext
    -> (Match a -> RELocation -> Capture a -> Maybe a)
    -> Matches a
    -> a
    replaceAllCaptures REContext
    TOP Match a -> RELocation -> Capture a -> Maybe a
    phi (Matches a -> a) -> Matches a -> a
    forall a b. (a -> b) -> a -> b
    $ a -> Matches a
    forall a.
    (Replace a, RegexContext Regex a (Matches a),
     RegexMaker Regex CompOption ExecOption [Char]) =>
    a -> Matches a
    scan_template a
    tpl
      where
        phi :: Match a -> RELocation -> Capture a -> Maybe a
    phi Match a
    t_mtch RELocation
    _ Capture a
    _ = (a -> Maybe a)
    -> (CaptureID -> Maybe a) -> Either a CaptureID -> Maybe a
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either a -> Maybe a
    forall a. a -> Maybe a
    Just CaptureID -> Maybe a
    this (Either a CaptureID -> Maybe a) -> Either a CaptureID -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ (a -> [Char]) -> Match a -> Either a CaptureID
    forall a. (a -> [Char]) -> Match a -> Either a CaptureID
    parse_template_capture a -> [Char]
    unpack Match a
    t_mtch

        this :: CaptureID -> Maybe a
    this CaptureID
    cid       = Capture a -> a
    forall a. Capture a -> a
    capturedText (Capture a -> a) -> Maybe (Capture a) -> Maybe a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Match a
    mtch Match a -> CaptureID -> Maybe (Capture a)
    forall a. Match a -> CaptureID -> Maybe (Capture a)
    !$? CaptureID
    cid
    \end{code}

    Helpers
    -------

    \begin{code}
    fixpoint :: (Eq a) => (a->a) -> a -> a
    fixpoint :: forall a. Eq a => (a -> a) -> a -> a
    fixpoint a -> a
    f = [a] -> a
    forall {a}. Eq a => [a] -> a
    chk ([a] -> a) -> (a -> [a]) -> a -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> a) -> a -> [a]
    forall a. (a -> a) -> a -> [a]
    iterate a -> a
    f
      where
        chk :: [a] -> a
    chk (a
    x:a
    x':[a]
    _) | a
    xa -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    ==a
    x' = a
    x
        chk [a]
    xs               = [a] -> a
    chk ([a] -> a) -> [a] -> a
    forall a b. (a -> b) -> a -> b
    $ [a] -> [a]
    forall a. HasCallStack => [a] -> [a]
    tail [a]
    xs
    \end{code}

    \begin{code}
    ($=~) :: ( RegexContext Regex source target
             , RegexMaker   Regex CompOption ExecOption String
             )
          => source -> String -> target
    $=~ :: forall source target.
    (RegexContext Regex source target,
     RegexMaker Regex CompOption ExecOption [Char]) =>
    source -> [Char] -> target
    ($=~) = source -> [Char] -> target
    forall source source1 target.
    (RegexMaker Regex CompOption ExecOption source,
     RegexContext Regex source1 target) =>
    source1 -> source -> target
    (=~)
    \end{code}