diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -64,6 +64,8 @@
 
 &nbsp;&nbsp;&nbsp;&nbsp;&#x2612;&nbsp;&nbsp;2017-03-18  v0.9.0.0  [Finish tidying up the API, Add type-safe replacement templates and exploit TemplateHaskellQuotes](https://github.com/iconnect/regex/milestone/9)
 
+&nbsp;&nbsp;&nbsp;&nbsp;&#x2612;&nbsp;&nbsp;2017-03-18  v0.10.0.0 [Tweak TypeSafe SearchReplace templates](https://github.com/iconnect/regex/milestone/11)
+
 &nbsp;&nbsp;&nbsp;&nbsp;&#x2610;&nbsp;&nbsp;2017-03-31  v1.0.0.0  [First stable release](https://github.com/iconnect/regex/milestone/3)
 
 &nbsp;&nbsp;&nbsp;&nbsp;&#x2610;&nbsp;&nbsp;2017-08-31  v2.0.0.0  [Fast text replacement with benchmarks](https://github.com/iconnect/regex/milestone/4)
diff --git a/Text/RE/Internal/SearchReplace/TDFA.hs b/Text/RE/Internal/SearchReplace/TDFA.hs
new file mode 100644
--- /dev/null
+++ b/Text/RE/Internal/SearchReplace/TDFA.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE NoImplicitPrelude          #-}
+{-# LANGUAGE CPP                        #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# LANGUAGE TemplateHaskellQuotes      #-}
+#else
+{-# LANGUAGE QuasiQuotes                #-}
+{-# LANGUAGE TemplateHaskell            #-}
+#endif
+
+module Text.RE.Internal.SearchReplace.TDFA
+  ( ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_
+  ) where
+
+import           Language.Haskell.TH
+import           Language.Haskell.TH.Quote
+import           Prelude.Compat
+import           Text.RE.Internal.SearchReplace.TDFAEdPrime
+import           Text.RE.Types.REOptions
+
+
+-- | the @[ed| ... /// ... |]@ quasi quoters
+ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_ :: QuasiQuoter
+
+ed                       = ed' cast $ Just minBound
+edMS                     = edMultilineSensitive
+edMI                     = edMultilineInsensitive
+edBS                     = edBlockSensitive
+edBI                     = edBlockInsensitive
+edMultilineSensitive     = ed' cast $ Just  MultilineSensitive
+edMultilineInsensitive   = ed' cast $ Just  MultilineInsensitive
+edBlockSensitive         = ed' cast $ Just  BlockSensitive
+edBlockInsensitive       = ed' cast $ Just  BlockInsensitive
+ed_                      = ed' cast   Nothing
+
+cast :: Q Exp
+cast = [|id|]
diff --git a/Text/RE/Internal/SearchReplace/TDFA/ByteString.hs b/Text/RE/Internal/SearchReplace/TDFA/ByteString.hs
new file mode 100644
--- /dev/null
+++ b/Text/RE/Internal/SearchReplace/TDFA/ByteString.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE CPP                        #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# LANGUAGE TemplateHaskellQuotes      #-}
+#else
+{-# LANGUAGE QuasiQuotes                #-}
+{-# LANGUAGE TemplateHaskell            #-}
+#endif
+
+module Text.RE.Internal.SearchReplace.TDFA.ByteString
+  ( ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_
+  ) where
+
+import qualified Data.ByteString.Char8         as B
+import           Language.Haskell.TH
+import           Language.Haskell.TH.Quote
+import           Text.RE.TDFA.RE
+import           Text.RE.Internal.SearchReplace.TDFAEdPrime
+import           Text.RE.SearchReplace
+import           Text.RE.Types.REOptions
+
+
+-- | the @[ed| ... /// ... |]@ quasi quoters
+ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_ :: QuasiQuoter
+
+ed                       = ed' sr_cast $ Just minBound
+edMS                     = edMultilineSensitive
+edMI                     = edMultilineInsensitive
+edBS                     = edBlockSensitive
+edBI                     = edBlockInsensitive
+edMultilineSensitive     = ed' sr_cast $ Just  MultilineSensitive
+edMultilineInsensitive   = ed' sr_cast $ Just  MultilineInsensitive
+edBlockSensitive         = ed' sr_cast $ Just  BlockSensitive
+edBlockInsensitive       = ed' sr_cast $ Just  BlockInsensitive
+ed_                      = ed' fn_cast   Nothing
+
+sr_cast :: Q Exp
+sr_cast = [|\x -> x :: SearchReplace RE B.ByteString|]
+
+fn_cast :: Q Exp
+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE B.ByteString|]
diff --git a/Text/RE/Internal/SearchReplace/TDFA/ByteString/Lazy.hs b/Text/RE/Internal/SearchReplace/TDFA/ByteString/Lazy.hs
new file mode 100644
--- /dev/null
+++ b/Text/RE/Internal/SearchReplace/TDFA/ByteString/Lazy.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE CPP                        #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# LANGUAGE TemplateHaskellQuotes      #-}
+#else
+{-# LANGUAGE QuasiQuotes                #-}
+{-# LANGUAGE TemplateHaskell            #-}
+#endif
+
+module Text.RE.Internal.SearchReplace.TDFA.ByteString.Lazy
+  ( ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_
+  ) where
+
+import qualified Data.ByteString.Lazy.Char8    as LBS
+import           Language.Haskell.TH
+import           Language.Haskell.TH.Quote
+import           Text.RE.TDFA.RE
+import           Text.RE.Internal.SearchReplace.TDFAEdPrime
+import           Text.RE.SearchReplace
+import           Text.RE.Types.REOptions
+
+
+-- | the @[ed| ... /// ... |]@ quasi quoters
+ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_ :: QuasiQuoter
+
+ed                       = ed' sr_cast $ Just minBound
+edMS                     = edMultilineSensitive
+edMI                     = edMultilineInsensitive
+edBS                     = edBlockSensitive
+edBI                     = edBlockInsensitive
+edMultilineSensitive     = ed' sr_cast $ Just  MultilineSensitive
+edMultilineInsensitive   = ed' sr_cast $ Just  MultilineInsensitive
+edBlockSensitive         = ed' sr_cast $ Just  BlockSensitive
+edBlockInsensitive       = ed' sr_cast $ Just  BlockInsensitive
+ed_                      = ed' fn_cast   Nothing
+
+sr_cast :: Q Exp
+sr_cast = [|\x -> x :: SearchReplace RE LBS.ByteString|]
+
+fn_cast :: Q Exp
+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE LBS.ByteString|]
diff --git a/Text/RE/Internal/SearchReplace/TDFA/Sequence.hs b/Text/RE/Internal/SearchReplace/TDFA/Sequence.hs
new file mode 100644
--- /dev/null
+++ b/Text/RE/Internal/SearchReplace/TDFA/Sequence.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE CPP                        #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# LANGUAGE TemplateHaskellQuotes      #-}
+#else
+{-# LANGUAGE QuasiQuotes                #-}
+{-# LANGUAGE TemplateHaskell            #-}
+#endif
+
+module Text.RE.Internal.SearchReplace.TDFA.Sequence
+  ( ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_
+  ) where
+
+import qualified Data.Sequence                 as S
+import           Language.Haskell.TH
+import           Language.Haskell.TH.Quote
+import           Text.RE.TDFA.RE
+import           Text.RE.Internal.SearchReplace.TDFAEdPrime
+import           Text.RE.SearchReplace
+import           Text.RE.Types.REOptions
+
+
+-- | the @[ed| ... /// ... |]@ quasi quoters
+ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_ :: QuasiQuoter
+
+ed                       = ed' sr_cast $ Just minBound
+edMS                     = edMultilineSensitive
+edMI                     = edMultilineInsensitive
+edBS                     = edBlockSensitive
+edBI                     = edBlockInsensitive
+edMultilineSensitive     = ed' sr_cast $ Just  MultilineSensitive
+edMultilineInsensitive   = ed' sr_cast $ Just  MultilineInsensitive
+edBlockSensitive         = ed' sr_cast $ Just  BlockSensitive
+edBlockInsensitive       = ed' sr_cast $ Just  BlockInsensitive
+ed_                      = ed' fn_cast   Nothing
+
+sr_cast :: Q Exp
+sr_cast = [|\x -> x :: SearchReplace RE (S.Seq Char)|]
+
+fn_cast :: Q Exp
+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE (S.Seq Char)|]
diff --git a/Text/RE/Internal/SearchReplace/TDFA/String.hs b/Text/RE/Internal/SearchReplace/TDFA/String.hs
new file mode 100644
--- /dev/null
+++ b/Text/RE/Internal/SearchReplace/TDFA/String.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE CPP                        #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# LANGUAGE TemplateHaskellQuotes      #-}
+#else
+{-# LANGUAGE QuasiQuotes                #-}
+{-# LANGUAGE TemplateHaskell            #-}
+#endif
+
+module Text.RE.Internal.SearchReplace.TDFA.String
+  ( ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_
+  ) where
+
+
+import           Language.Haskell.TH
+import           Language.Haskell.TH.Quote
+import           Text.RE.TDFA.RE
+import           Text.RE.Internal.SearchReplace.TDFAEdPrime
+import           Text.RE.SearchReplace
+import           Text.RE.Types.REOptions
+
+
+-- | the @[ed| ... /// ... |]@ quasi quoters
+ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_ :: QuasiQuoter
+
+ed                       = ed' sr_cast $ Just minBound
+edMS                     = edMultilineSensitive
+edMI                     = edMultilineInsensitive
+edBS                     = edBlockSensitive
+edBI                     = edBlockInsensitive
+edMultilineSensitive     = ed' sr_cast $ Just  MultilineSensitive
+edMultilineInsensitive   = ed' sr_cast $ Just  MultilineInsensitive
+edBlockSensitive         = ed' sr_cast $ Just  BlockSensitive
+edBlockInsensitive       = ed' sr_cast $ Just  BlockInsensitive
+ed_                      = ed' fn_cast   Nothing
+
+sr_cast :: Q Exp
+sr_cast = [|\x -> x :: SearchReplace RE String|]
+
+fn_cast :: Q Exp
+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE String|]
diff --git a/Text/RE/Internal/SearchReplace/TDFA/Text.hs b/Text/RE/Internal/SearchReplace/TDFA/Text.hs
new file mode 100644
--- /dev/null
+++ b/Text/RE/Internal/SearchReplace/TDFA/Text.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE CPP                        #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# LANGUAGE TemplateHaskellQuotes      #-}
+#else
+{-# LANGUAGE QuasiQuotes                #-}
+{-# LANGUAGE TemplateHaskell            #-}
+#endif
+
+module Text.RE.Internal.SearchReplace.TDFA.Text
+  ( ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_
+  ) where
+
+import qualified Data.Text                     as T
+import           Language.Haskell.TH
+import           Language.Haskell.TH.Quote
+import           Text.RE.TDFA.RE
+import           Text.RE.Internal.SearchReplace.TDFAEdPrime
+import           Text.RE.SearchReplace
+import           Text.RE.Types.REOptions
+
+
+-- | the @[ed| ... /// ... |]@ quasi quoters
+ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_ :: QuasiQuoter
+
+ed                       = ed' sr_cast $ Just minBound
+edMS                     = edMultilineSensitive
+edMI                     = edMultilineInsensitive
+edBS                     = edBlockSensitive
+edBI                     = edBlockInsensitive
+edMultilineSensitive     = ed' sr_cast $ Just  MultilineSensitive
+edMultilineInsensitive   = ed' sr_cast $ Just  MultilineInsensitive
+edBlockSensitive         = ed' sr_cast $ Just  BlockSensitive
+edBlockInsensitive       = ed' sr_cast $ Just  BlockInsensitive
+ed_                      = ed' fn_cast   Nothing
+
+sr_cast :: Q Exp
+sr_cast = [|\x -> x :: SearchReplace RE T.Text|]
+
+fn_cast :: Q Exp
+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE T.Text|]
diff --git a/Text/RE/Internal/SearchReplace/TDFA/Text/Lazy.hs b/Text/RE/Internal/SearchReplace/TDFA/Text/Lazy.hs
new file mode 100644
--- /dev/null
+++ b/Text/RE/Internal/SearchReplace/TDFA/Text/Lazy.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE CPP                        #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# LANGUAGE TemplateHaskellQuotes      #-}
+#else
+{-# LANGUAGE QuasiQuotes                #-}
+{-# LANGUAGE TemplateHaskell            #-}
+#endif
+
+module Text.RE.Internal.SearchReplace.TDFA.Text.Lazy
+  ( ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_
+  ) where
+
+import qualified Data.Text.Lazy                as TL
+import           Language.Haskell.TH
+import           Language.Haskell.TH.Quote
+import           Text.RE.TDFA.RE
+import           Text.RE.Internal.SearchReplace.TDFAEdPrime
+import           Text.RE.SearchReplace
+import           Text.RE.Types.REOptions
+
+
+-- | the @[ed| ... /// ... |]@ quasi quoters
+ed
+  , edMS
+  , edMI
+  , edBS
+  , edBI
+  , edMultilineSensitive
+  , edMultilineInsensitive
+  , edBlockSensitive
+  , edBlockInsensitive
+  , ed_ :: QuasiQuoter
+
+ed                       = ed' sr_cast $ Just minBound
+edMS                     = edMultilineSensitive
+edMI                     = edMultilineInsensitive
+edBS                     = edBlockSensitive
+edBI                     = edBlockInsensitive
+edMultilineSensitive     = ed' sr_cast $ Just  MultilineSensitive
+edMultilineInsensitive   = ed' sr_cast $ Just  MultilineInsensitive
+edBlockSensitive         = ed' sr_cast $ Just  BlockSensitive
+edBlockInsensitive       = ed' sr_cast $ Just  BlockInsensitive
+ed_                      = ed' fn_cast   Nothing
+
+sr_cast :: Q Exp
+sr_cast = [|\x -> x :: SearchReplace RE TL.Text|]
+
+fn_cast :: Q Exp
+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE TL.Text|]
diff --git a/Text/RE/Internal/SearchReplace/TDFAEdPrime.hs b/Text/RE/Internal/SearchReplace/TDFAEdPrime.hs
new file mode 100644
--- /dev/null
+++ b/Text/RE/Internal/SearchReplace/TDFAEdPrime.hs
@@ -0,0 +1,63 @@
+{-# LANGUAGE NoImplicitPrelude          #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE CPP                        #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
+{-# LANGUAGE TemplateHaskellQuotes      #-}
+#else
+{-# LANGUAGE QuasiQuotes                #-}
+{-# LANGUAGE TemplateHaskell            #-}
+#endif
+
+module Text.RE.Internal.SearchReplace.TDFAEdPrime
+  ( ed'
+  ) where
+
+import           Language.Haskell.TH
+import           Language.Haskell.TH.Quote
+import           Prelude.Compat
+import           Text.RE.Internal.SearchReplace
+import           Text.RE.Internal.QQ
+import           Text.RE.TDFA.RE
+import           Text.RE.SearchReplace
+import           Text.RE.Types.IsRegex
+import           Text.RE.Types.REOptions
+import           Text.RE.Types.Replace
+import           Text.Regex.TDFA
+
+
+-- | construct a quasi quoter from a casting function and @Just sro@
+-- if the options are known, otherwise a function take takes the
+-- 'SimpleREOptions' and constructs the 'SearchReplace' template
+ed' :: Q Exp -> Maybe SimpleREOptions -> QuasiQuoter
+ed' qe mb = case mb of
+  Nothing  ->
+    (qq0 "ed'")
+      { quoteExp = parse minBound $ \rs -> AppE <$> qe <*> [|flip unsafe_compile_sr rs|]
+      }
+  Just sro ->
+    (qq0 "ed'")
+      { quoteExp = parse sro $ \rs -> AppE <$> qe <*> [|unsafe_compile_sr_simple sro rs|]
+      }
+  where
+    parse :: SimpleREOptions -> (String->Q Exp) -> String -> Q Exp
+    parse sro mk ts = either error (\_->mk ts) ei
+      where
+        ei :: Either String (SearchReplace RE String)
+        ei = compileSearchReplace_ id (compileRegexWith sro) ts
+
+unsafe_compile_sr_simple :: IsRegex RE s
+                         => SimpleREOptions
+                         -> String
+                         -> SearchReplace RE s
+unsafe_compile_sr_simple sro =
+    unsafe_compile_sr $ unpackSimpleREOptions sro
+
+unsafe_compile_sr :: ( IsOption o RE CompOption ExecOption
+                              , IsRegex RE s
+                              )
+                           => o
+                           -> String
+                           -> SearchReplace RE s
+unsafe_compile_sr os =
+    unsafeCompileSearchReplace_ packR $ compileRegexWithOptions os
diff --git a/Text/RE/SearchReplace.hs b/Text/RE/SearchReplace.hs
--- a/Text/RE/SearchReplace.hs
+++ b/Text/RE/SearchReplace.hs
@@ -1,18 +1,4 @@
-{-# LANGUAGE NoImplicitPrelude          #-}
 {-# LANGUAGE RecordWildCards            #-}
-{-# LANGUAGE MultiParamTypeClasses      #-}
-{-# LANGUAGE TypeSynonymInstances       #-}
-{-# LANGUAGE FlexibleInstances          #-}
-{-# LANGUAGE FlexibleContexts           #-}
-{-# LANGUAGE CPP                        #-}
-#if __GLASGOW_HASKELL__ >= 800
-{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
-{-# LANGUAGE TemplateHaskellQuotes      #-}
-#else
-{-# LANGUAGE QuasiQuotes                #-}
-{-# LANGUAGE TemplateHaskell            #-}
-#endif
-{-# OPTIONS_GHC -fno-warn-orphans       #-}
 
 module Text.RE.SearchReplace
   (
@@ -20,80 +6,17 @@
     SearchReplace(..)
   , searchReplaceFirst
   , searchReplaceAll
-  , unsafeCompileSearchReplace_
-  , compileSearchReplace_
-  , compileSearchAndReplace_
   ) where
 
-import qualified Data.HashMap.Strict            as HMS
-import           Prelude.Compat
-import           Text.RE.Internal.NamedCaptures
-import           Text.RE.Types.Capture
-import           Text.RE.Types.CaptureID
 import           Text.RE.Types.IsRegex
-import           Text.RE.Types.Matches
 import           Text.RE.Types.Replace
 import           Text.RE.Types.SearchReplace
-import qualified Text.Regex.TDFA                as TDFA
 
 
--- | search and replace
-searchReplaceAll, searchReplaceFirst :: IsRegex re s => SearchReplace re s -> s -> s
-searchReplaceAll   SearchReplace{..} = replaceAll getTemplate . matchMany getSearch
-searchReplaceFirst SearchReplace{..} = replace    getTemplate . matchOnce getSearch
-
--- | warapper on 'compileSearchReplace_' that will generate an error
--- if any compilation errors are found
-unsafeCompileSearchReplace_ :: (String->s)
-                            -> (String->Either String re)
-                            -> String
-                            -> SearchReplace re s
-unsafeCompileSearchReplace_ pk cf = either err id . compileSearchReplace_ pk cf
-  where
-    err msg = error $ "unsafeCompileSearchReplace_: " ++ msg
-
--- | compile a SearchReplace template generating errors if the RE or
--- the template are not well formed -- all capture references being checked
-compileSearchReplace_ :: (Monad m,Functor m)
-                      => (String->s)
-                      -> (String->Either String re)
-                      -> String
-                      -> m (SearchReplace re s)
-compileSearchReplace_ pack compile_re sr_tpl = either fail return $ do
-    case mainCaptures $ sr_tpl $=~ "///" of
-      [cap] ->
-        compileSearchAndReplace_ pack compile_re
-                      (capturePrefix cap) (captureSuffix cap)
-      _ -> Left $ "bad search-replace template syntax: " ++ sr_tpl
-
--- | compile 'SearcgReplace' from two strings containing the RE
--- and the replacement template
-compileSearchAndReplace_ :: (Monad m,Functor m)
-                         => (String->s)
-                         -> (String->Either String re)
-                         -> String
-                         -> String
-                         -> m (SearchReplace re s)
-compileSearchAndReplace_ pack compile_re re_s tpl = either fail return $ do
-    re           <- compile_re re_s
-    ((n,cnms),_) <- extractNamedCaptures re_s
-    mapM_ (check n cnms) $ templateCaptures id tpl
-    return $ SearchReplace re $ pack tpl
-  where
-    check :: Int -> CaptureNames -> CaptureID -> Either String ()
-    check n cnms cid = case cid of
-      IsCaptureOrdinal co -> check_co n    co
-      IsCaptureName    cn -> check_cn cnms cn
-
-    check_co n (CaptureOrdinal i) = case i <= n of
-      True  -> return ()
-      False -> Left $ "capture ordinal out of range: " ++
-                                      show i ++ " >= " ++ show n
-
-    check_cn cnms cnm = case cnm `HMS.member` cnms of
-      True  -> return ()
-      False -> Left $ "capture name not defined: " ++
-                                      show (getCaptureName cnm)
+-- | searching and replacing the first occurrence
+searchReplaceAll :: IsRegex re s => SearchReplace re s -> s -> s
+searchReplaceAll SearchReplace{..} = replaceAll getTemplate . matchMany getSearch
 
-($=~) :: String -> String -> Matches String
-($=~) = (TDFA.=~)
+-- | searching and replaceing all occurrences
+searchReplaceFirst :: IsRegex re s => SearchReplace re s -> s -> s
+searchReplaceFirst SearchReplace{..} = replace    getTemplate . matchOnce getSearch
diff --git a/Text/RE/TDFA.hs b/Text/RE/TDFA.hs
--- a/Text/RE/TDFA.hs
+++ b/Text/RE/TDFA.hs
@@ -41,6 +41,8 @@
   , escape
   , escapeWith
   , module Text.RE.TDFA.RE
+  -- * The [ed| ... |] quasi quoters
+  , module Text.RE.Internal.SearchReplace.TDFA
   -- * The Operator Instances
   -- $instances
   , module Text.RE.TDFA.ByteString
@@ -54,6 +56,7 @@
 import qualified Text.Regex.Base                          as B
 import           Text.RE
 import           Text.RE.Internal.AddCaptureNames
+import           Text.RE.Internal.SearchReplace.TDFA
 import           Text.RE.TDFA.RE
 import qualified Text.Regex.TDFA                          as TDFA
 import           Text.RE.SearchReplace
@@ -113,5 +116,4 @@
 
 -- $instances
 --
--- These modules merely provide the instances for the above regex
--- match operators at the various text types.
+-- These modules merely provide the 'IsRegex' instances.
diff --git a/Text/RE/TDFA/ByteString.hs b/Text/RE/TDFA/ByteString.hs
--- a/Text/RE/TDFA/ByteString.hs
+++ b/Text/RE/TDFA/ByteString.hs
@@ -44,6 +44,7 @@
   , escape
   , escapeWith
   , module Text.RE.TDFA.RE
+  , module Text.RE.Internal.SearchReplace.TDFA.ByteString
   ) where
 
 import           Prelude.Compat
@@ -52,6 +53,7 @@
 import           Text.Regex.Base
 import           Text.RE
 import           Text.RE.Internal.AddCaptureNames
+import           Text.RE.Internal.SearchReplace.TDFA.ByteString
 import           Text.RE.SearchReplace
 import           Text.RE.Types.IsRegex
 import           Text.RE.Types.REOptions
diff --git a/Text/RE/TDFA/ByteString/Lazy.hs b/Text/RE/TDFA/ByteString/Lazy.hs
--- a/Text/RE/TDFA/ByteString/Lazy.hs
+++ b/Text/RE/TDFA/ByteString/Lazy.hs
@@ -44,6 +44,7 @@
   , escape
   , escapeWith
   , module Text.RE.TDFA.RE
+  , module Text.RE.Internal.SearchReplace.TDFA.ByteString.Lazy
   ) where
 
 import           Prelude.Compat
@@ -52,6 +53,7 @@
 import           Text.Regex.Base
 import           Text.RE
 import           Text.RE.Internal.AddCaptureNames
+import           Text.RE.Internal.SearchReplace.TDFA.ByteString.Lazy
 import           Text.RE.SearchReplace
 import           Text.RE.Types.IsRegex
 import           Text.RE.Types.REOptions
diff --git a/Text/RE/TDFA/RE.hs b/Text/RE/TDFA/RE.hs
--- a/Text/RE/TDFA/RE.hs
+++ b/Text/RE/TDFA/RE.hs
@@ -59,16 +59,16 @@
   , reBlockSensitive
   , reBlockInsensitive
   , re_
-  , ed
-  , edMS
-  , edMI
-  , edBS
-  , edBI
-  , edMultilineSensitive
-  , edMultilineInsensitive
-  , edBlockSensitive
-  , edBlockInsensitive
-  , ed_
+  -- , ed
+  -- , edMS
+  -- , edMI
+  -- , edBS
+  -- , edBI
+  -- , edMultilineSensitive
+  -- , edMultilineInsensitive
+  -- , edBlockSensitive
+  -- , edBlockInsensitive
+  -- , ed_
   , cp
   ) where
 
@@ -80,6 +80,7 @@
 import           Text.RE.Internal.NamedCaptures
 import           Text.RE.Internal.PreludeMacros
 import           Text.RE.Internal.QQ
+import           Text.RE.Internal.SearchReplace
 import           Text.RE.SearchReplace
 import           Text.RE.TestBench
 import           Text.RE.Types.CaptureID
@@ -328,17 +329,17 @@
   , reMultilineInsensitive
   , reBlockSensitive
   , reBlockInsensitive
-  , re_
-  , ed
-  , edMS
-  , edMI
-  , edBS
-  , edBI
-  , edMultilineSensitive
-  , edMultilineInsensitive
-  , edBlockSensitive
-  , edBlockInsensitive
-  , ed_ :: QuasiQuoter
+  , re_ :: QuasiQuoter
+  -- , ed
+  -- , edMS
+  -- , edMI
+  -- , edBS
+  -- , edBI
+  -- , edMultilineSensitive
+  -- , edMultilineInsensitive
+  -- , edBlockSensitive
+  -- , edBlockInsensitive
+  -- , ed_ :: QuasiQuoter
 
 re                       = re' $ Just minBound
 reMS                     = reMultilineSensitive
@@ -351,16 +352,16 @@
 reBlockInsensitive       = re' $ Just  BlockInsensitive
 re_                      = re'   Nothing
 
-ed                       = ed' $ Just minBound
-edMS                     = edMultilineSensitive
-edMI                     = edMultilineInsensitive
-edBS                     = edBlockSensitive
-edBI                     = edBlockInsensitive
-edMultilineSensitive     = ed' $ Just  MultilineSensitive
-edMultilineInsensitive   = ed' $ Just  MultilineInsensitive
-edBlockSensitive         = ed' $ Just  BlockSensitive
-edBlockInsensitive       = ed' $ Just  BlockInsensitive
-ed_                      = ed'   Nothing
+-- ed                       = ed' $ Just minBound
+-- edMS                     = edMultilineSensitive
+-- edMI                     = edMultilineInsensitive
+-- edBS                     = edBlockSensitive
+-- edBI                     = edBlockInsensitive
+-- edMultilineSensitive     = ed' $ Just  MultilineSensitive
+-- edMultilineInsensitive   = ed' $ Just  MultilineInsensitive
+-- edBlockSensitive         = ed' $ Just  BlockSensitive
+-- edBlockInsensitive       = ed' $ Just  BlockInsensitive
+-- ed_                      = ed'   Nothing
 
 
 ------------------------------------------------------------------------
@@ -428,39 +429,39 @@
 -- ed Helpers
 ------------------------------------------------------------------------
 
-ed' :: Maybe SimpleREOptions -> QuasiQuoter
-ed' mb = case mb of
-  Nothing  ->
-    (qq0 "ed'")
-      { quoteExp = parse minBound (\rs->[|flip unsafeCompileSearchReplace rs|])
-      }
-  Just sro ->
-    (qq0 "ed'")
-      { quoteExp = parse sro (\rs->[|unsafeCompileSearchReplaceSimple sro rs|])
-      }
-  where
-    parse :: SimpleREOptions -> (String->Q Exp) -> String -> Q Exp
-    parse sro mk ts = either error (\_->mk ts) ei
-      where
-        ei :: Either String (SearchReplace RE String)
-        ei = compileSearchReplace_ id (compileRegexWith sro) ts
-
-unsafeCompileSearchReplaceSimple :: IsRegex RE s
-                                 => SimpleREOptions
-                                 -> String
-                                 -> SearchReplace RE s
-unsafeCompileSearchReplaceSimple sro re_s = unsafeCompileSearchReplace os re_s
-  where
-    os = unpackSimpleREOptions sro
-
-unsafeCompileSearchReplace :: ( IsOption o RE CompOption ExecOption
-                              , IsRegex RE s
-                              )
-                           => o
-                           -> String
-                           -> SearchReplace RE s
-unsafeCompileSearchReplace os =
-    unsafeCompileSearchReplace_ packR $ compileRegexWithOptions os
+-- ed' :: Maybe SimpleREOptions -> QuasiQuoter
+-- ed' mb = case mb of
+--   Nothing  ->
+--     (qq0 "ed'")
+--       { quoteExp = parse minBound (\rs->[|flip unsafeCompileSearchReplace rs|])
+--       }
+--   Just sro ->
+--     (qq0 "ed'")
+--       { quoteExp = parse sro (\rs->[|unsafeCompileSearchReplaceSimple sro rs|])
+--       }
+--   where
+--     parse :: SimpleREOptions -> (String->Q Exp) -> String -> Q Exp
+--     parse sro mk ts = either error (\_->mk ts) ei
+--       where
+--         ei :: Either String (SearchReplace RE String)
+--         ei = compileSearchReplace_ id (compileRegexWith sro) ts
+--
+-- unsafeCompileSearchReplaceSimple :: IsRegex RE s
+--                                  => SimpleREOptions
+--                                  -> String
+--                                  -> SearchReplace RE s
+-- unsafeCompileSearchReplaceSimple sro re_s = unsafeCompileSearchReplace os re_s
+--   where
+--     os = unpackSimpleREOptions sro
+--
+-- unsafeCompileSearchReplace :: ( IsOption o RE CompOption ExecOption
+--                               , IsRegex RE s
+--                               )
+--                            => o
+--                            -> String
+--                            -> SearchReplace RE s
+-- unsafeCompileSearchReplace os =
+--     unsafeCompileSearchReplace_ packR $ compileRegexWithOptions os
 
 
 ------------------------------------------------------------------------
diff --git a/Text/RE/TDFA/Sequence.hs b/Text/RE/TDFA/Sequence.hs
--- a/Text/RE/TDFA/Sequence.hs
+++ b/Text/RE/TDFA/Sequence.hs
@@ -44,6 +44,7 @@
   , escape
   , escapeWith
   , module Text.RE.TDFA.RE
+  , module Text.RE.Internal.SearchReplace.TDFA.Sequence
   ) where
 
 import           Prelude.Compat
@@ -52,6 +53,7 @@
 import           Text.Regex.Base
 import           Text.RE
 import           Text.RE.Internal.AddCaptureNames
+import           Text.RE.Internal.SearchReplace.TDFA.Sequence
 import           Text.RE.SearchReplace
 import           Text.RE.Types.IsRegex
 import           Text.RE.Types.REOptions
diff --git a/Text/RE/TDFA/String.hs b/Text/RE/TDFA/String.hs
--- a/Text/RE/TDFA/String.hs
+++ b/Text/RE/TDFA/String.hs
@@ -44,6 +44,7 @@
   , escape
   , escapeWith
   , module Text.RE.TDFA.RE
+  , module Text.RE.Internal.SearchReplace.TDFA.String
   ) where
 
 import           Prelude.Compat
@@ -52,6 +53,7 @@
 import           Text.Regex.Base
 import           Text.RE
 import           Text.RE.Internal.AddCaptureNames
+import           Text.RE.Internal.SearchReplace.TDFA.String
 import           Text.RE.SearchReplace
 import           Text.RE.Types.IsRegex
 import           Text.RE.Types.REOptions
diff --git a/Text/RE/TDFA/Text.hs b/Text/RE/TDFA/Text.hs
--- a/Text/RE/TDFA/Text.hs
+++ b/Text/RE/TDFA/Text.hs
@@ -44,6 +44,7 @@
   , escape
   , escapeWith
   , module Text.RE.TDFA.RE
+  , module Text.RE.Internal.SearchReplace.TDFA.Text
   ) where
 
 import           Prelude.Compat
@@ -52,6 +53,7 @@
 import           Text.Regex.Base
 import           Text.RE
 import           Text.RE.Internal.AddCaptureNames
+import           Text.RE.Internal.SearchReplace.TDFA.Text
 import           Text.RE.SearchReplace
 import           Text.RE.Types.IsRegex
 import           Text.RE.Types.REOptions
diff --git a/Text/RE/TDFA/Text/Lazy.hs b/Text/RE/TDFA/Text/Lazy.hs
--- a/Text/RE/TDFA/Text/Lazy.hs
+++ b/Text/RE/TDFA/Text/Lazy.hs
@@ -44,6 +44,7 @@
   , escape
   , escapeWith
   , module Text.RE.TDFA.RE
+  , module Text.RE.Internal.SearchReplace.TDFA.Text.Lazy
   ) where
 
 import           Prelude.Compat
@@ -52,6 +53,7 @@
 import           Text.Regex.Base
 import           Text.RE
 import           Text.RE.Internal.AddCaptureNames
+import           Text.RE.Internal.SearchReplace.TDFA.Text.Lazy
 import           Text.RE.SearchReplace
 import           Text.RE.Types.IsRegex
 import           Text.RE.Types.REOptions
diff --git a/Text/RE/Tools/Edit.lhs b/Text/RE/Tools/Edit.lhs
--- a/Text/RE/Tools/Edit.lhs
+++ b/Text/RE/Tools/Edit.lhs
@@ -47,7 +47,7 @@
 data Edit m re s
   = Template !(SearchReplace re s)
   | Function !re REContext !(LineNo->Match s->Location->Capture s->m (Maybe s))
-  | LineEdit !re         !(LineNo->Matches s->m (LineEdit s))
+  | LineEdit !re           !(LineNo->Matches s->m (LineEdit s))
 
 -- | a LineEdit is the most general action thar can be performed on a line
 -- and is the only means of deleting a line
diff --git a/Text/RE/Types/IsRegex.lhs b/Text/RE/Types/IsRegex.lhs
--- a/Text/RE/Types/IsRegex.lhs
+++ b/Text/RE/Types/IsRegex.lhs
@@ -8,6 +8,7 @@
 
 module Text.RE.Types.IsRegex where
 
+import           Text.RE.Internal.EscapeREString
 import           Text.RE.Types.Match
 import           Text.RE.Types.Matches
 import           Text.RE.Types.REOptions
@@ -15,7 +16,6 @@
 import           Text.RE.Types.SearchReplace
 \end{code}
 
-
 \begin{code}
 -- | the 'IsRegex' class allows tools to be written that will work with
 -- regex back end text type supported by the back end
@@ -32,9 +32,15 @@
   makeSearchReplace     :: (Functor m,Monad m,IsRegex re s) => s -> s -> m (SearchReplace re s)
   -- | compiling a 'SearchReplace' template specifing the 'SimpleREOptions' for the RE
   makeSearchReplaceWith :: (Functor m,Monad m,IsRegex re s) => SimpleREOptions -> s -> s -> m (SearchReplace re s)
+  -- | incorporate an escaped string into a compiled RE with the default options
+  makeEscaped           :: (Functor m,Monad m) => (s->s) -> s -> m re
+  -- | incorporate an escaped string into a compiled RE with the specified 'SimpleREOptions'
+  makeEscapedWith       :: (Functor m,Monad m) => SimpleREOptions -> (s->s) -> s -> m re
   -- | extract the text of the RE from the RE
   regexSource           :: re -> s
 
-  makeRegex         = makeRegexWith         minBound
-  makeSearchReplace = makeSearchReplaceWith minBound
+  makeRegex           = makeRegexWith         minBound
+  makeSearchReplace   = makeSearchReplaceWith minBound
+  makeEscaped         = makeEscapedWith       minBound
+  makeEscapedWith o f = makeRegexWith o . f . packR . escapeREString . unpackR
 \end{code}
diff --git a/Text/RE/Types/SearchReplace.hs b/Text/RE/Types/SearchReplace.hs
--- a/Text/RE/Types/SearchReplace.hs
+++ b/Text/RE/Types/SearchReplace.hs
@@ -1,25 +1,7 @@
-{-# LANGUAGE NoImplicitPrelude          #-}
-{-# LANGUAGE RecordWildCards            #-}
-{-# LANGUAGE MultiParamTypeClasses      #-}
-{-# LANGUAGE TypeSynonymInstances       #-}
-{-# LANGUAGE FlexibleInstances          #-}
-{-# LANGUAGE FlexibleContexts           #-}
-{-# LANGUAGE CPP                        #-}
-#if __GLASGOW_HASKELL__ >= 800
-{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
-{-# LANGUAGE TemplateHaskellQuotes      #-}
-#else
-{-# LANGUAGE QuasiQuotes                #-}
-{-# LANGUAGE TemplateHaskell            #-}
-#endif
-{-# OPTIONS_GHC -fno-warn-orphans       #-}
 
 module Text.RE.Types.SearchReplace
   ( SearchReplace(..)
   ) where
-
-import           Prelude.Compat
-
 
 -- | contains a compiled RE and replacement template
 data SearchReplace re s =
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,5 +1,9 @@
 -*-change-log-*-
 
+0.10.0.0 Chris Dornan <chris.dornan@irisconnect.co.uk> 2017-03-25
+  * Tweak Type-Safe SearchReplace templates (#86)
+  * Add escape methods to IsRegex (#87)
+
 0.9.0.0 Chris Dornan <chris.dornan@irisconnect.co.uk> 2017-03-23
   * Flip the order of the arguments to replace (#78)
   * Add type-safe replacement templates (#60)
diff --git a/regex.cabal b/regex.cabal
--- a/regex.cabal
+++ b/regex.cabal
@@ -1,5 +1,5 @@
 Name:                   regex
-Version:                0.9.0.0
+Version:                0.10.0.0
 Synopsis:               Toolkit for regex-base
 Description:            A Regular Expression Toolkit for regex-base with
                         Compile-time checking of RE syntax, data types for
@@ -31,20 +31,20 @@
 Source-Repository this
     Type:               git
     Location:           https://github.com/iconnect/regex.git
-    Tag:                0.9.0.0
+    Tag:                0.10.0.0
 
 
 
 
 Library
     Hs-Source-Dirs:     .
+
     Exposed-Modules:
       Text.RE
       Text.RE.Internal.AddCaptureNames
       Text.RE.Internal.EscapeREString
       Text.RE.Internal.NamedCaptures
       Text.RE.Internal.PreludeMacros
-      Text.RE.Internal.QQ
       Text.RE.SearchReplace
       Text.RE.Summa
       Text.RE.TDFA
@@ -72,6 +72,17 @@
       Text.RE.Types.REOptions
       Text.RE.Types.Replace
       Text.RE.Types.SearchReplace
+
+    Other-Modules:
+      Text.RE.Internal.QQ
+      Text.RE.Internal.SearchReplace.TDFA
+      Text.RE.Internal.SearchReplace.TDFA.ByteString
+      Text.RE.Internal.SearchReplace.TDFA.ByteString.Lazy
+      Text.RE.Internal.SearchReplace.TDFA.Sequence
+      Text.RE.Internal.SearchReplace.TDFA.String
+      Text.RE.Internal.SearchReplace.TDFA.Text
+      Text.RE.Internal.SearchReplace.TDFA.Text.Lazy
+      Text.RE.Internal.SearchReplace.TDFAEdPrime
 
     Default-Language:   Haskell2010
 
