diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,11 @@
+#####   3.0
+  *API overhaul*
+  minimize use of newtypes
+  regex-constructing functions catch error, return Either String a
+  Format is now Replace.Template
+  fix bug in ReplaceOpen.getGroup    
+  hide Matchf
+
 #####   2.6.2
   compatible with 2.6.1
   
diff --git a/regex-do.cabal b/regex-do.cabal
--- a/regex-do.cabal
+++ b/regex-do.cabal
@@ -1,5 +1,5 @@
 name:                regex-do
-version:             2.6.2
+version:             3.0
 synopsis:            PCRE wrapper
 description:         format, search, replace (String | ByteString) with PCRE regex. Utf8-safe
 author:              Imants Cekusins
@@ -19,27 +19,26 @@
 library
   exposed-modules:
           Text.Regex.Do.Trim
-          Text.Regex.Do.Pcre.Option
-          Text.Regex.Do.Pcre.Utf8.Replace
+          Text.Regex.Do.Match.Option
+          Text.Regex.Do.Replace.Utf8
           Text.Regex.Do.Split
-          Text.Regex.Do.Format
+          Text.Regex.Do.Replace.Template
           Text.Regex.Do.Type.Do
-          Text.Regex.Do.Type.Reexport
-          Text.Regex.Do.Convert
+          Text.Regex.Do.Type.Convert
           Text.Regex.Do.Pad
-          Text.Regex.Do.Pcre.Ascii.MatchHint
-          Text.Regex.Do.ReplaceOpen
+          Text.Regex.Do.Replace.Open
           Text.Regex.Do.Type.Extract
-          Text.Regex.Do.Type.Regex
+          Text.Regex.Do.Match.Regex
           Text.Regex.Do.Type.MatchHint
-          Text.Regex.Do.Pcre.Ascii.Match
-          Text.Regex.Do.Pcre.Ascii.Replace
-          Text.Regex.Do.Pcre.Utf8.Match
-          Text.Regex.Do.Pcre.Utf8.MatchHint
-          Text.Regex.Do.Pcre.Matchf
-
+          Text.Regex.Do.Match.Latin
+          Text.Regex.Do.Replace.Latin
+          Text.Regex.Do.Match.Utf8
+          Text.Regex.Do.Replace.Fast
   other-modules:
-          Text.Regex.Do.Result
+          Text.Regex.Do.Match.Result
+          Text.Regex.Do.Match.Matchf
+          Text.Regex.Do.Type.Reexport
+          
   ghc-options:  -fwarn-unused-imports
     
   build-depends:  base <= 5.0,
@@ -47,6 +46,7 @@
               regex-pcre,
               stringsearch,
               bytestring,
+              tagged,
               mtl,
               array,
               text
@@ -64,6 +64,7 @@
                         ScopedTypeVariables
                         DeriveFunctor
                         TypeFamilies
+                        FunctionalDependencies
                        
 
 test-suite spec
@@ -81,6 +82,7 @@
                         ScopedTypeVariables
                         DeriveFunctor
                         TypeFamilies
+                        FunctionalDependencies
 
 
   main-is: Main.hs
@@ -99,6 +101,7 @@
                   QuickCheck,
                   regex-base,
                   regex-pcre,
+                  tagged,
                   stringsearch,
                   mtl,
                   bytestring,
diff --git a/src/Text/Regex/Do/Convert.hs b/src/Text/Regex/Do/Convert.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Convert.hs
+++ /dev/null
@@ -1,33 +0,0 @@
-module Text.Regex.Do.Convert where
-
-import qualified Data.Text.Encoding as E
-import qualified Data.Text as T
-import Data.ByteString as B
-import Text.Regex.Do.Type.Do
-import Text.Regex.Base.RegexLike as R
-import Data.Array as A
-import Prelude as P
-
-
--- | both Ascii and Utf8
-toByteString::String -> ByteString
-toByteString = E.encodeUtf8 . T.pack
-
-toByteString'::String -> Utf8_ ByteString
-toByteString' = Utf8_ . toByteString
-
--- | both Ascii and Utf8
-toString::ByteString -> String
-toString = T.unpack . E.decodeUtf8
-
-
-
-class ToArray a where
-    toArray::a -> MatchArray
-
-instance ToArray MatchArray where
-    toArray = id
-
-instance ToArray [PosLen] where
-    toArray [] = listArray (0,0) []
-    toArray lpl0 = listArray (1, P.length lpl0) lpl0
diff --git a/src/Text/Regex/Do/Format.hs b/src/Text/Regex/Do/Format.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Format.hs
+++ /dev/null
@@ -1,132 +0,0 @@
-{- | ==== placeholder syntax:
-
-       * index based
-
-            { Int }
-
-       * key based
-
-            { 'String' | 'ByteString' | 'Text' }
-
-    other placeholders may be implemented with
-
-    "Text.Regex.Do.Pcre.Ascii.Replace" or "Text.Regex.Do.Pcre.Utf8.Replace"       -}
-
-module Text.Regex.Do.Format
-    (Format(..),
-    ReplaceOne(..),
-    Formatable) where
-
-import Prelude as P
-import Text.Regex.Do.Type.Do
-import Text.Regex.Do.Split as S (replace)
-import Text.Regex.Do.Convert
-import Data.ByteString as B
-import Data.Text as T
-
-
-type Formatable a = (Format a [a], Format a [(a,a)])
-
-{- | ==== implemented a:
-
-    * 'String'
-    * 'ByteString'
-    * 'Text'      -}
-
-class Format a arg where
-   format::a    -- ^ text to format e.g. "today is {0}"
-        -> arg  -- ^ replacement: [a] or [(a,a)]
-        -> a    -- ^ formatted text
-
-
-instance ReplaceOne Int a =>
-    Format a [a] where
-   format = foldr_idx foldFn_idx
-{- ^ === index based
-     >>> format "на первое {0}, на второе {0}" ["перловка"]
-
-     "на первое перловка, на второе перловка"
-
-     >>> format "Polly {0} a {1}" ["got","cracker"]
-
-     "Polly got a cracker"
--}
-
-foldFn_idx::ReplaceOne k v =>
-    v -> (k, v) -> v
-foldFn_idx v0 (i0, body1) = replaceOne body1 i0 v0
-
-
-
-instance ReplaceOne a a =>
-    Format a [(a, a)] where
-   format = P.foldr foldFn_map
-{- ^=== key based
-     key may be {any a}
-
-     >>> format "овчинка {a} не {b}" [("a","выделки"),("b","стоит")]
-
-     "овчинка выделки не стоит"
--}
-
-
-
-foldFn_map::ReplaceOne k v =>
-    (k, v) -> v -> v
-foldFn_map (k0, v0) body1 = replaceOne body1 k0 v0
-
-
-
---  fold with index
-type CustomerFn a b = (a -> (Int,b) -> b)
-
-foldr_idx::CustomerFn a b -> b -> [a] -> b
-foldr_idx fn0 init1 list0 = b1
-   where i0 = P.length list0 - 1
-         (-1,b1) = P.foldr (foldFn fn0) (i0,init1) list0
-
-
-foldFn::CustomerFn a b -> a -> (Int, b) -> (Int, b)
-foldFn fn0 val0 t0@(i0, _) = (i0 - 1, b1)
-   where b1 = fn0 val0 t0
-
-
-class ReplaceOne idx a where
-    replaceOne::a -> idx -> a -> a
-
-
-instance ReplaceOne Int String where
-    replaceOne body0 k0 v0 = toString bs1
-       where pat1 = Pattern $ toByteString $ "{" ++ (show k0) ++ "}"
-             repl1 = Replacement $ toByteString v0
-             bs1 = S.replace pat1 repl1 $ Body $ toByteString body0
-
-
-instance ReplaceOne String String where
-    replaceOne body0 k0 v0 = toString bs1
-       where pat1 = Pattern $ toByteString $ "{" ++ k0 ++ "}"
-             repl1 = Replacement $ toByteString v0
-             bs1 = S.replace pat1 repl1 $ Body $ toByteString body0
-
-
-instance ReplaceOne Int ByteString where
-    replaceOne body0 k0 v0 = S.replace pat1 repl1 $ Body body0
-       where pat1 = Pattern $ toByteString $ "{" ++ (show k0) ++ "}"
-             repl1 = Replacement v0
-
-
-instance ReplaceOne ByteString ByteString where
-    replaceOne body0 k0 v0 = S.replace pat1 repl1 $ Body body0
-       where pat1 = Pattern $ B.concat [toByteString "{", k0, toByteString "}"]
-             repl1 = Replacement v0
-
-
-
-instance ReplaceOne Int Text where
-    replaceOne body0 k0 v0 = T.replace pat1 v0 body0
-       where pat1 = T.pack $ "{" ++ (show k0) ++ "}"
-
-
-instance ReplaceOne Text Text where
-    replaceOne body0 k0 v0 = T.replace pat1 v0 body0
-       where pat1 = T.concat [T.pack "{", k0, T.pack "}"]
diff --git a/src/Text/Regex/Do/Match/Latin.hs b/src/Text/Regex/Do/Match/Latin.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Match/Latin.hs
@@ -0,0 +1,163 @@
+{- | although sometimes funs in Ascii modules work with non-ascii text
+    (as some examples show),
+    for reliable results with Utf8 pattern or body,
+    use "Text.Regex.Do.Pcre.Match.Utf8"
+
+    see also "Text.Regex.Base.RegexLike" -}
+
+module Text.Regex.Do.Match.Latin
+    (MatchOnce(..),
+    MatchAll(..),
+    R.extract   -- | 'extract' is reexport from "Text.Regex.Base.RegexLike"
+    ) where
+
+import qualified Text.Regex.Base.RegexLike as R hiding (makeRegex)
+import Text.Regex.Do.Type.Do
+import Text.Regex.Do.Match.Matchf as F
+import Text.Regex.PCRE.Wrap()
+import Text.Regex.Do.Type.MatchHint
+import Text.Regex.Do.Match.Regex as R
+import Text.Regex.Do.Type.Reexport as Re
+import Data.Tagged
+
+
+{- | === API changes: 
+    
+    Once is hinted with '~?' 
+    
+    All is hinted with '~*'   
+
+    All regex-computing instances catch regex errors, return 'Either' 'String' out ('Left' String is the error message)
+    
+    * pattern:  'String', 'ByteString', 'Regex'
+    
+        String | ByteString pattern may contains regex
+
+    * body:  'String', 'ByteString'
+    * out: out | E out
+
+        * 'Bool': test if regex matches
+        * ['String']
+        * ['ByteString']
+        * ['PosLen']
+
+
+    precompiled Regex may be used as pattern too. see "Text.Regex.Do.Pcre.Match.Utf8"  -}
+class MatchOnce pattern body out where
+    (~?)::pattern -> body -> out
+
+{- | * pattern:  'String', 'ByteString', 'Regex'
+    * body:  'String', 'ByteString'
+    * out: out | E out
+
+        * [['String']]
+        * [['ByteString']]
+        * [['PosLen']]
+-}
+class MatchAll pattern body out where
+    (~*)::pattern -> body -> out
+
+
+instance R.RegexLike Re.Regex b => MatchOnce Re.Regex b [b]  where
+    (~?) pat0 body0 = once pat0 (Tagged body0)
+-- ^ always succeeds               
+
+
+instance (R.Regex b, R.RegexLike Re.Regex b) => 
+        MatchOnce b b (E [b])  where     
+    (~?) pat0 body0 = withRegex pat0 (Tagged body0) once
+{- ^  >>> "^all" ~? "all the time"::E [String]
+        
+     Right \["all"]      -}
+
+instance (R.Regex b, R.RegexLike Re.Regex b) =>
+        MatchOnce b b (E Bool) where
+    (~?) pat0 body0 = withRegex pat0 (tagB body0) test
+        where tagB::b -> Tagged Test b
+              tagB = Tagged
+{- ^ test
+
+    >>> "chilly" ~? "it's chilly inside, chilly outside"::E Bool
+
+    Right True    -}
+              
+
+instance R.RegexLike Re.Regex b =>
+        MatchOnce Re.Regex b Bool where
+    (~?) pat0 body0 = test pat0 (tagB body0) 
+        where tagB::b -> Tagged Test b
+              tagB = Tagged    
+{- ^ test.
+
+always succeeds -}               
+
+
+instance R.RegexLike Re.Regex b =>
+    MatchAll Re.Regex b [[b]] where
+    (~*) pat0 body0 = F.all pat0 (Tagged body0)
+-- ^ always succeeds               
+
+
+instance (R.Regex b, R.RegexLike Re.Regex b) =>
+        MatchAll b b (E [[b]]) where
+    (~*) pat0 body0 = withRegex pat0 (Tagged body0) F.all 
+{- ^ @ 
+"chilly" ~* "it's chilly inside, chilly outside"::E [[ByteString]]
+
+Right \[\["chilly"],["chilly"]]   
+     @     -}
+
+
+instance R.RegexLike Re.Regex b =>
+        MatchOnce Re.Regex b [PosLen] where
+    (~?) pat0 body0 = r1 
+      where tagOne::b -> Tagged Once b
+            tagOne = Tagged
+            Right r1 = poslen_ (Right pat0) (tagOne body0)
+-- ^ always succeeds               
+
+
+instance (R.Regex b, R.RegexLike Re.Regex b) =>
+        MatchOnce b b (E [PosLen]) where
+    (~?) pat0 body0 = withRegex' pat0 (tagOne body0) poslen_
+      where tagOne::b -> Tagged Once b
+            tagOne = Tagged
+      
+{-^ >>> "à" ~? "tourner à gauche"::E [PosLen]
+
+  Right \[(8,2)]     -}
+
+
+instance R.RegexLike Re.Regex b =>
+        MatchAll Re.Regex b [[PosLen]] where
+    (~*) pat0 body0 = r1 
+      where tagAll::b -> Tagged All b
+            tagAll = Tagged
+            Right r1 = poslen_ (Right pat0) (tagAll body0)
+-- ^ always succeeds               
+
+
+instance (R.Regex b, R.RegexLike Re.Regex b) =>
+        MatchAll b b (E [[PosLen]]) where
+    (~*) pat0 body0 = withRegex' pat0 (tagAll body0) poslen_
+      where tagAll::b -> Tagged All b
+            tagAll = Tagged
+
+
+
+withRegex::(R.Regex a, R.RegexLike Re.Regex b) =>
+    a ->        --  pattern 
+    hint b ->   --  body
+    (Re.Regex -> hint b -> out) -> 
+        E out
+withRegex p0 b0 fn0 = makeRegex p0 >>= \p1 ->
+        Right $ fn0 p1 b0
+
+
+withRegex'::(R.Regex a, Matchf hint) =>
+    a -> hint b ->
+        (E Re.Regex -> hint b -> P hint) ->
+        P hint
+withRegex' p0 b0 fn0 = 
+        let er1 = makeRegex p0 
+        in fn0 er1 b0  
diff --git a/src/Text/Regex/Do/Match/Matchf.hs b/src/Text/Regex/Do/Match/Matchf.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Match/Matchf.hs
@@ -0,0 +1,66 @@
+-- | __internal__ module, exposed only to show the instances
+module Text.Regex.Do.Match.Matchf where
+
+import Text.Regex.Do.Type.Do
+import Text.Regex.Do.Type.Reexport as R
+import Text.Regex.Do.Match.Result as R
+import Text.Regex.Base.RegexLike as R
+import Text.Regex.Do.Type.MatchHint
+import Data.Tagged
+import Data.ByteString as B 
+
+
+type R_ b = R.RegexLike R.Regex b
+
+
+class Matchf hint where
+    type H hint
+    type P hint
+    marray_::R_ b => E R.Regex -> hint b -> H hint
+    poslen_::R_ b => E R.Regex -> hint b -> P hint
+    
+    
+instance Matchf (Tagged Once) where
+    type H (Tagged Once) = E (Maybe MatchArray)
+    type P (Tagged Once) = E [PosLen]
+    marray_ ep0 (Tagged b0) = ep0 >>= \ep1 -> Right $ R.matchOnce ep1 b0 
+    poslen_ ep0 (Tagged b0) = ep0 >>= \ep1 -> 
+                let mpl1 = R.poslen $ R.matchOnce ep1 b0::Maybe [PosLen]
+                in Right $ maybe [] id mpl1 
+
+
+instance Matchf (Tagged All) where
+    type H (Tagged All) = E [MatchArray]
+    type P (Tagged All) = E [[PosLen]]
+    marray_ ep0 (Tagged b0) = ep0 >>= \ep1 -> Right $ R.matchAll ep1 b0
+    poslen_ ep0 (Tagged b0) = ep0 >>= \ep1 -> Right $ R.poslen $ R.matchAll ep1 b0
+
+
+once::(R_ b, R.Extract b) =>
+    R.Regex -> Tagged Once b -> [b]      -- ^ matched content
+once p0 t0@(Tagged b0) = maybe [] id $ R.allMatches (Body b0) r1 
+    where Right r1 = marray_ (Right p0) t0   
+
+
+all::(R_ b, R.Extract b) =>
+    R.Regex -> Tagged All b -> [[b]]       -- ^ matched content
+all p0 t0@(Tagged b0) = R.allMatches (Body b0) r1 
+    where Right r1 = marray_ (Right p0) t0
+
+
+test::(R_ b, R.Extract b) =>
+    R.Regex -> Tagged Test b -> Bool      -- ^ matched content
+test p0 t0@(Tagged b0) = R.matchTest p0 b0
+
+
+
+tagOnce::b -> Tagged Once b
+tagOnce = Tagged
+
+tagAll::b -> Tagged All b
+tagAll = Tagged
+
+
+checkPattern::ByteString -> ByteString
+checkPattern bs0 = if bs0 == B.empty then error "empty pattern"
+      else bs0
diff --git a/src/Text/Regex/Do/Match/Option.hs b/src/Text/Regex/Do/Match/Option.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Match/Option.hs
@@ -0,0 +1,143 @@
+module Text.Regex.Do.Match.Option (
+      Comp(..),
+      Exec(..),
+      comp,
+      exec
+   ) where
+
+import Data.Bits
+import qualified Text.Regex.PCRE.ByteString as B
+
+
+-- | <http://www.pcre.org/pcre.txt pcre man pages>
+
+data Comp = Blank       {- ^ 'B.compBlank'
+
+                            clears default options: extended,caseSensitive,multiline regex
+                        -}
+
+            | Anchored  {- ^ 'B.compAnchored'
+
+            the pattern is forced to be "anchored", that is, it
+       is  constrained to match only at the first matching point in the string
+       that is being searched (the "subject string").
+
+       This effect can also  be achieved  by appropriate constructs in the pattern itself. -}
+
+            | Caseless  {- ^ 'B.compCaseless'
+
+            letters in the pattern match both upper  and  lower case  letters.
+
+            It  is  equivalent  to  Perl's /i option, and it can be changed within a pattern by a (?i) option setting.
+
+       In UTF-8 mode,  PCRE always  understands the concept of case for characters whose values are
+       less than 128, so caseless matching is always possible. For  characters with  higher  values,  the concept of case is supported if PCRE is compiled with Unicode property support.
+        If you want  to use  caseless  matching  for  characters 128 and above, you must ensure
+       that PCRE is compiled with Unicode property support  as  well  as  with UTF-8 support.   -}
+
+            | Dotall    {- ^ 'B.compDotAll'
+
+            a dot metacharacter in the pattern matches a  character of any value,
+            including one that indicates a newline.
+
+            However, it only ever matches one character, even if newlines are  coded  as  CRLF.
+
+       Without  this option, a dot does not match when the current position is
+       at a newline.
+
+       This option is equivalent to Perl's /s option, and it can be  changed within a pattern by a (?s) option setting.
+
+       A negative class such as [^a] always matches newline characters, independent of the setting of this option. -}
+
+            | Multiline {- ^ 'B.compMultiline'
+
+            By default, for the purposes of matching "start of line"  and  "end  of
+       line", PCRE treats the subject string as consisting of a single line of
+       characters, even if it actually contains newlines. The "start of  line"
+       metacharacter (^) matches only at the start of the string, and the "end
+       of line" metacharacter ($) matches only at the end of  the  string,  or
+       before  a terminating newline (except when PCRE_DOLLAR_ENDONLY is set).
+       Note, however, that unless PCRE_DOTALL  is  set,  the  "any  character"
+       metacharacter  (.)  does not match at a newline. This behaviour (for ^,
+       $, and dot) is the same as Perl.
+
+       When PCRE_MULTILINE it is set, the "start of line" and  "end  of  line"
+       constructs  match  immediately following or immediately before internal
+       newlines in the subject string, respectively, as well as  at  the  very
+       start  and  end.
+
+       This is equivalent to Perl's /m option, and it can be
+       changed within a pattern by a (?m) option setting.
+
+       If there are no newlines  in  a  subject string, or no occurrences of ^ or $ in a pattern,
+       setting PCRE_MULTILINE has no effect.    -}
+
+            | Utf8      {- ^ 'B.compUTF8'
+
+            This option causes PCRE to regard both the pattern and the  subject  as
+       strings of UTF-8 characters instead of single-byte strings. However, it
+       is available only when PCRE is built to include UTF  support.  If  not,
+       the  use  of  this option provokes an error. Details of how this option
+       changes the behaviour of PCRE are given in the pcreunicode page.     -}
+
+            | Ungreedy  {- ^ 'B.compUngreedy'
+
+            This  option  inverts  the "greediness" of the quantifiers so that they
+       are not greedy by default, but become greedy if followed by "?".
+
+       It can also be set by a (?U) option setting within the pattern.  -}
+   deriving (Eq,Ord,Enum)
+
+
+data Exec = BlankE  {- ^ 'B.execBlank'
+
+                    clears default options: extended,caseSensitive,multiline regex      -}
+            | NotEmpty  {- ^ 'B.execNotEmpty'
+
+            An empty string is not considered to be a valid match if this option is
+       set. If there are alternatives in the pattern, they are tried.  If  all
+       the  alternatives  match  the empty string, the entire match fails. For
+       example, if the pattern
+
+         a?b?
+
+       is applied to a string not beginning with "a" or  "b",  it  matches  an
+       empty  string at the start of the subject. With PCRE_NOTEMPTY set, this
+       match is not valid, so PCRE searches further into the string for occurrences of "a" or "b".        -}
+
+            | Partial   {- ^ 'B.execPartial'
+
+            see PCREPARTIAL(3)  in <http://www.pcre.org/pcre.txt pcre man pages>    -}
+   deriving (Eq,Ord,Enum)
+
+
+compOpt::Comp -> B.CompOption
+compOpt o = case o of
+   Blank -> B.compBlank
+   Anchored -> B.compAnchored
+   Caseless -> B.compCaseless
+   Dotall -> B.compDotAll
+   Multiline -> B.compMultiline
+   Utf8 -> B.compUTF8
+   Ungreedy -> B.compUngreedy
+
+
+comp::[Comp] -> B.CompOption
+comp [] = B.compBlank
+comp l = foldl (.&.) o0 l1
+   where l1 = compOpt <$> l
+         o0 = compOpt $ head l
+
+
+execOpt::Exec -> B.ExecOption
+execOpt o =   case o of
+   BlankE -> B.execBlank
+   NotEmpty -> B.execNotEmpty
+   Partial -> B.execPartial
+
+
+exec::[Exec] -> B.ExecOption
+exec [] = B.execBlank
+exec l = foldl (.&.) o0 l1
+   where l1 = execOpt <$> l
+         o0 = execOpt $ head l
diff --git a/src/Text/Regex/Do/Match/Regex.hs b/src/Text/Regex/Do/Match/Regex.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Match/Regex.hs
@@ -0,0 +1,65 @@
+module Text.Regex.Do.Match.Regex
+    (Regex(..),
+    E(..)) where
+
+import qualified Text.Regex.Base.RegexLike as R
+import qualified Text.Regex.Do.Type.Reexport as R
+import Data.ByteString
+import Text.Regex.Do.Type.Do
+import Text.Regex.Do.Match.Option
+import Data.List as L
+
+
+
+
+class Regex a where
+   makeRegex::a -> E R.Regex
+   makeRegexOpt::a -> [Comp] -> [Exec] -> E R.Regex
+
+
+instance Regex ByteString where
+   makeRegex p0 = rre $ R.makeRegexM p0 
+   makeRegexOpt p0 o0 e0 = rre $ makeRegexOptsM p0 o0 e0 
+
+
+instance Regex String where
+   makeRegex p0 = rre $ R.makeRegexM p0
+   makeRegexOpt p0 o0 e0 = rre $ makeRegexOptsM p0 o0 e0 
+
+
+instance Regex R.Regex where
+   makeRegex p0 = pure p0
+   makeRegexOpt p0 _ _ = pure p0
+
+
+makeRegexOptsM::(Monad m, Opt_ a) =>
+    a -> [Comp] -> [Exec] ->
+            m R.Regex
+makeRegexOptsM pat0 comp0 exec0 = rx1
+   where c1 = comp comp0
+         e1 = exec exec0
+         rx1 = R.makeRegexOptsM c1 e1 pat0
+
+
+-- | internal type
+type Opt_ a = R.RegexMaker R.Regex R.CompOption R.ExecOption a
+
+
+rre::RegexResult a -> Either String a
+rre (RegexResult e0) = either (Left . (L.intercalate " ")) Right e0
+
+
+{- | catches regex construction __errors__  -}
+newtype RegexResult a = RegexResult (Either [String] a) deriving (Functor)
+
+instance Applicative RegexResult where
+    pure = RegexResult . Right
+    (<*>) (RegexResult (Left e1)) (RegexResult (Left e2)) = RegexResult $ Left $ e1 ++ e2
+    (<*>) (RegexResult (Right fn0)) (RegexResult (Left e1)) = RegexResult $ Left e1
+    (<*>) (RegexResult (Left e1)) (RegexResult (Right r1)) = RegexResult $ Left e1
+    (<*>) (RegexResult (Right fn0)) (RegexResult (Right a0)) = pure $ fn0 a0
+
+instance Monad RegexResult where
+    (>>=) (RegexResult (Left e1)) fn0 = RegexResult $ Left e1
+    (>>=) (RegexResult (Right a0)) fn0 = fn0 a0
+    fail s0 = RegexResult $ Left [s0]
diff --git a/src/Text/Regex/Do/Match/Result.hs b/src/Text/Regex/Do/Match/Result.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Match/Result.hs
@@ -0,0 +1,22 @@
+module Text.Regex.Do.Match.Result where
+
+import qualified Data.Array as A(elems)
+import Text.Regex.Base.RegexLike as R
+import Text.Regex.Do.Type.Do
+
+-- | match offset, length
+poslen::Functor f =>
+    f MatchArray -> f [PosLen]
+poslen = (A.elems <$>)
+
+
+-- | all groups
+allMatches::(Functor f, R.Extract b) =>
+    Body b -> f MatchArray -> f [b]
+allMatches hay0 results0 = groupMatch hay0 <$> results0
+
+
+-- | matches for one group
+groupMatch::R.Extract b =>
+    Body b -> MatchArray -> [b]
+groupMatch (Body b0) a0 = [R.extract tuple1 b0 |  tuple1 <- A.elems a0]
diff --git a/src/Text/Regex/Do/Match/Utf8.hs b/src/Text/Regex/Do/Match/Utf8.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Match/Utf8.hs
@@ -0,0 +1,215 @@
+{- | see "Text.Regex.Base.RegexLike" 
+
+    see "Text.Regex.Do.Pcre.Match.Latin" for API changes
+
+    __'toByteString'__ converts String to utf8 'ByteString'     -}
+module Text.Regex.Do.Match.Utf8
+    (MatchOnce(..),
+    MatchAll(..),
+    R.extract   -- | 'extract' is reexport from "Text.Regex.Base.RegexLike"
+    ) where
+
+import Data.Tagged
+import qualified Text.Regex.Base.RegexLike as R hiding (makeRegex)
+import Text.Regex.Do.Type.Do
+import Text.Regex.Do.Match.Matchf as F
+import Text.Regex.PCRE.Wrap()
+import Text.Regex.Do.Match.Regex as T
+import Text.Regex.Do.Type.MatchHint
+import Text.Regex.Do.Match.Option
+import Text.Regex.Do.Type.Reexport as Re
+import Data.ByteString
+import Text.Regex.Do.Type.Convert
+
+
+{- | * pattern:  'String', 'ByteString', 'Regex'      compile 'Re.Regex' with 'Utf8' opt
+
+        String | ByteString pattern may contains regex
+    
+    * body:  'String', 'ByteString'
+    * out: out | E out
+
+        * 'Bool'  :  test if regex matches
+        * ['String'] 
+        * ['ByteString']
+        * ['PosLen']    -}
+class MatchOnce pattern body out where
+    (~?)::pattern -> body -> out
+
+
+{- | * pattern:  'String', 'ByteString', 'Re.Regex'      compile 'Re.Regex' with 'Utf8' opt
+    * body:  'String', 'ByteString'
+    * out:
+
+        * [['String']]
+        * [['ByteString']]
+        * [['PosLen']]      -}
+class MatchAll pattern body out where
+    (~*)::pattern -> body -> out
+
+
+{- | b: 'String', 'ByteString' 
+
+    always succeeds               
+
+==== precompiled regex as pattern
+
+@    
+let rx1 = makeRegexOpt (toByteString "左") [Utf8] []      --  add options as needed
+    m1 = rx1 -? (toByteString "100メートル左折後、左")::[ByteString]
+m1 `shouldBe` [toByteString "左"]       
+@ -}
+
+instance R.RegexLike Re.Regex b => 
+        MatchOnce Re.Regex b [b] where
+    (~?) pat0 body0 = once pat0 (Tagged body0)
+
+
+instance R.RegexLike Re.Regex b => 
+        MatchOnce Re.Regex b Bool where
+    (~?) pat0 body0 = test pat0 (Tagged body0)
+{- ^ b: 'String', 'ByteString' 
+
+always succeeds     -}
+
+
+instance R.RegexLike Re.Regex b =>
+        MatchOnce Re.Regex b [PosLen] where
+    (~?) pat0 body0 = r1
+        where tagOne::b -> Tagged Once b
+              tagOne = Tagged 
+              Right r1 = poslen_ (Right pat0) (tagOne body0)
+{- ^ b: 'String', 'ByteString' 
+
+always succeeds     -}
+
+
+instance MatchOnce String String (E [String]) where
+    (~?) pat0 body0 = withRegex pat0 (tagB body0) once
+        where tagB::b -> Tagged Once b
+              tagB = Tagged
+{- ^ >>> ("^熱"::String) ~? ("熱い午後"::String)::E [String]
+
+Right \["熱"]     -}
+
+
+instance MatchOnce ByteString ByteString (E [ByteString]) where
+    (~?) pat0 body0 = withRegex pat0 (tagB body0) once
+        where tagB::b -> Tagged Once b
+              tagB = Tagged
+
+
+instance MatchOnce String String (E Bool) where
+    (~?) pat0 body0 = withRegex pat0 (tagB body0) test
+        where tagB::b -> Tagged Test b
+              tagB = Tagged
+{- ^ test
+
+>>>  ("в"::String) ~? ("тихо в лесу"::String)::E Bool
+
+Right True        -}
+
+instance MatchOnce ByteString ByteString (E Bool) where
+    (~?) pat0 body0 = withRegex pat0 (tagB body0) test
+        where tagB::b -> Tagged Test b
+              tagB = Tagged
+
+
+instance MatchOnce ByteString ByteString (E [PosLen]) where
+    (~?) pat0 body0 = withRegex' pat0 (tagOne body0) poslen_
+      where tagOne::b -> Tagged Once b
+            tagOne = Tagged
+
+
+instance MatchOnce String String (E [PosLen]) where
+    (~?) pat0 body0 = withRegex' pat0 (tagOne body0) poslen_
+      where tagOne::b -> Tagged Once b
+            tagOne = Tagged
+
+
+instance R.RegexLike Re.Regex b =>
+        MatchAll Re.Regex b [[b]] where
+    (~*) pat0 body0 = F.all pat0 (Tagged body0)
+{- ^ b: 'String', 'ByteString' 
+
+always succeeds     -}
+
+
+
+instance MatchAll ByteString ByteString (E [[ByteString]]) where
+    (~*) pat0 body0 = withRegex pat0 (Tagged body0) F.all
+
+
+instance MatchAll String String (E [[String]]) where
+    (~*) pat0 body0 = withRegex pat0 (Tagged body0) F.all
+{- ^  >>> ("лес"::String) ~* ("Залесью, залесью…"::String)::E [[String]]
+
+Right \[["лес"],["лес"]]        -}
+
+
+instance R.RegexLike Re.Regex b =>
+        MatchAll Re.Regex b [[PosLen]] where
+    (~*) pat0 body0 = r1
+        where tagOne::b -> Tagged All b
+              tagOne = Tagged
+              Right r1 = poslen_ (Right pat0) (tagOne body0)
+{- ^ b: 'String', 'ByteString' 
+
+always succeeds     -}
+
+
+
+instance MatchAll String String (E [[PosLen]]) where
+    (~*) pat0 body0 = withRegex' pat0 (tagAll body0) poslen_
+      where tagAll::b -> Tagged All b
+            tagAll = Tagged
+
+
+instance MatchAll ByteString ByteString (E [[PosLen]]) where
+    (~*) pat0 body0 = withRegex' pat0 (tagAll body0) poslen_
+      where tagAll::b -> Tagged All b
+            tagAll = Tagged
+
+
+
+class WithRegex a out' out where
+    withRegex::(T.Regex a, R.RegexLike Re.Regex a, Functor hint) =>
+        a ->        --  pattern 
+        hint a ->   --  body
+        (Re.Regex -> hint ByteString -> out') ->
+            E out
+
+
+instance WithRegex ByteString out out where
+    withRegex p0 b0 fn0 = makeRegexOpt p0 [Utf8] [] >>= \p1 ->
+            Right $ fn0 p1 b0
+
+
+instance WithRegex String [ByteString] [String] where
+    withRegex p0 b0 fn0 = makeRegexOpt p1 [Utf8] [] >>= \p2 ->
+            Right $ toString <$> (fn0 p2 b1)
+        where p1 = toByteString p0
+              b1 = toByteString <$> b0
+
+
+instance WithRegex String [[ByteString]] [[String]] where
+    withRegex p0 b0 fn0 = makeRegexOpt p1 [Utf8] [] >>= \p2 ->
+            Right $ [(toString <$>)] <*> (fn0 p2 b1)
+        where p1 = toByteString p0
+              b1 = toByteString <$> b0
+
+
+instance WithRegex String Bool Bool where
+    withRegex p0 b0 fn0 = makeRegexOpt p1 [Utf8] [] >>= \p2 ->
+            Right $ fn0 p2 b1
+        where p1 = toByteString p0
+              b1 = toByteString <$> b0
+
+
+withRegex'::(T.Regex a, Matchf hint) =>
+    a -> hint b ->
+        (E Re.Regex -> hint b -> P hint) ->
+        P hint
+withRegex' p0 b0 fn0 =
+        let er1 = makeRegexOpt p0 [Utf8] []
+        in fn0 er1 b0  
diff --git a/src/Text/Regex/Do/Pcre/Ascii/Match.hs b/src/Text/Regex/Do/Pcre/Ascii/Match.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Pcre/Ascii/Match.hs
+++ /dev/null
@@ -1,86 +0,0 @@
-{- | although sometimes funs in Ascii modules work with non-ascii text
-    (as some examples show),
-    for reliable results with Utf8 pattern or body,
-    use "Text.Regex.Do.Pcre.Utf8.Match"
-
-    see also "Text.Regex.Base.RegexLike" and "Text.Regex.Do.Pcre.Ascii.MatchHint" -}
-
-module Text.Regex.Do.Pcre.Ascii.Match
-    (Match(..),
-    (=~),
-    R.extract   -- | 'extract' is reexport from "Text.Regex.Base.RegexLike"
-    ) where
-
-import qualified Text.Regex.Base.RegexLike as R hiding (makeRegex)
-import Text.Regex.Do.Type.Do
-import Text.Regex.Do.Pcre.Matchf as F
-import Text.Regex.PCRE.Wrap()
-import Text.Regex.Do.Type.Regex
-import Text.Regex.Do.Type.MatchHint
-
-
-{- | short version of 'match': arg without newtypes
-
-    is borrowed from "Text.Regex.PCRE.Wrap"    -}
-(=~)::Match a b out =>
-    a     -- ^ pattern
-    -> b    -- ^ body
-    -> out
-(=~) p0 b0 = match (Pattern p0) (Body b0)
-
-
-
-{- | * a:  'String', 'ByteString', 'Regex'
-    * b:  'String', 'ByteString'
-    * out:
-
-        * ['String'], [['String']]
-        * ['ByteString'], [['ByteString']]
-        * 'Bool'
-        * ['PosLen'], [['PosLen']]
-
-
-    precompiled Regex may be used as pattern too. see "Text.Regex.Do.Pcre.Utf8.Match"
-
-    See also "Text.Regex.Do.Pcre.Ascii.MatchHint"
-
-    to catch regex construction __errors__, precompile 'Regex' with 'makeRegexM' or 'makeRegexOptM'     -}
-
-class Match a b out where
-    match::Pattern a -> Body b -> out
-
-
-
-
--- | match once
-instance Rx_ a b => Match a b [b] where
-    match p0 = once (makeRegex' p0)
-{- ^  >>> "^all" =~ "all the time"::[String]
-
-     \["all"\]      -}
-instance Rx_ a b => Match a b Bool where
-    match p0 (Body b0) = R.matchTest (makeRegex p0) b0
-{- ^ test
-
-    >>> "chilly" =~ "it's chilly inside, chilly outside"::Bool
-
-    True    -}
-
--- | match all
-instance Rx_ a b => Match a b [[b]] where
-    match p0 = F.all (makeRegex' p0)
-{- ^  >>> "chilly" =~ "it's chilly inside, chilly outside"::[[ByteString]]
-
-     \[["chilly"\],\["chilly"\]]        -}
-
--- | match once
-instance Rx_ a b => Match a b [PosLen] where
-    match p0 b0 = maybe [] id $ poslen_ (Once $ makeRegex' p0) b0
-{- ^ >>> "à" =~ "tourner à gauche"::[PosLen]
-
-     \[(8,2)\]      -}
-
--- | match all
-instance Rx_ a b => Match a b [[PosLen]] where
-    match p0 = poslen_ $ All $ makeRegex' p0
-
diff --git a/src/Text/Regex/Do/Pcre/Ascii/MatchHint.hs b/src/Text/Regex/Do/Pcre/Ascii/MatchHint.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Pcre/Ascii/MatchHint.hs
+++ /dev/null
@@ -1,92 +0,0 @@
-{- | this module uses
-    <https://cdepillabout.github.io/haskell-type-families-presentation/#/ TypeFamilies>
-
-    this module is similar to "Text.Regex.Do.Pcre.Ascii.Match". The differences are:
-
-    * "Text.Regex.Do.Pcre.Ascii.Match" is more flexible:
-
-        accepts 'Pattern' Regex,
-
-        accepts 'Pattern' and 'Body' of different types
-
-    * "Text.Regex.Do.Pcre.Ascii.Match" needs to infer result type
-
-    this module:
-
-    * 'Pattern' and 'Body' are of the same type
-
-    * 'Hint' and inferrable 'Pattern' or 'Body' type determine the instance
-
-        the result type is determined by the hint
-
-    * handy when working with 'OverloadedStrings', in other cases when compiler needs a hint  -}
-
-module Text.Regex.Do.Pcre.Ascii.MatchHint where
-
-import Text.Regex.Do.Type.Do hiding (Once,All)
-import Text.Regex.PCRE.Wrap()
-import qualified Text.Regex.Do.Pcre.Ascii.Match as M
-import Text.Regex.Do.Type.MatchHint
-import Data.ByteString
-
-
-{- | * hint: 'Once', 'All', 'Test', 'PosLen'', 'PosLen_'
-    * a: 'String', 'ByteString'
--}
-
-
-class (Hint hint, M.Match a a (F hint a)) =>
-    MatchHint hint a where
-    type F hint a
-    match::hint (Pattern a) -> Body a -> F hint a
-    match h0 = M.match $ unhint h0
-
-(=~)::MatchHint hint a =>
-        hint a  -- ^ hint & pattern
-        -> a          -- ^ body
-        -> F hint a   -- ^ type defined by the instance, determined by the hint
-(=~) h0 = (M.=~) $ unhint h0
-
-
-instance MatchHint Test String where
-    type F Test String = Bool
-
-
-instance MatchHint PosLen' String where
-    type F PosLen' String = [PosLen]
-
-{- ^ >>> PosLen' ("и"::String) =~ "бывает и хуже"
-
-    \[(13,2)\]      -}
-
-instance MatchHint PosLen_ String where
-    type F PosLen_ String = [[PosLen]]
-
-instance MatchHint Once String where
-    type F Once String = [String]
-
-{- ^ >>> Once ("^all"::String) =~ "all the time"
-
-    \["all"\]       -}
-
-instance MatchHint All String where
-    type F All String = [[String]]
-
-instance MatchHint Test ByteString where
-    type F Test ByteString = Bool
-
-{- ^ >>> Test ("в"::ByteString) =~ "тихо в лесу"
-
-    True    -}
-
-instance MatchHint PosLen' ByteString where
-    type F PosLen' ByteString = [PosLen]
-
-instance MatchHint PosLen_ ByteString where
-    type F PosLen_ ByteString = [[PosLen]]
-
-instance MatchHint Once ByteString where
-    type F Once ByteString = [ByteString]
-
-instance MatchHint All ByteString where
-    type F All ByteString = [[ByteString]]
diff --git a/src/Text/Regex/Do/Pcre/Ascii/Replace.hs b/src/Text/Regex/Do/Pcre/Ascii/Replace.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Pcre/Ascii/Replace.hs
+++ /dev/null
@@ -1,152 +0,0 @@
-{- | for reliable results with Utf8 pattern or body,
-    use "Text.Regex.Do.Pcre.Utf8.Replace"   -}
-
-module Text.Regex.Do.Pcre.Ascii.Replace
-    (Replace(..),
-    Replace'(),
-    Repl_)  where
-
-import Text.Regex.Base.RegexLike as R
-import Prelude as P
-import Text.Regex.Do.Type.Do
-import Text.Regex.Do.Type.Reexport as R
-import Text.Regex.Do.Pcre.Matchf
-import qualified Text.Regex.Do.ReplaceOpen as O
-import Text.Regex.Do.Type.Regex as T
-import Text.Regex.Do.Type.Extract
-import Text.Regex.Do.Type.MatchHint
-import Text.Regex.Do.Pcre.Option as O
-
-{- | 'All' | 'Once' needs to be specified once with either pat, repl or body
-
-    * pat: a: 'String' | 'ByteString' | 'Regex'
-
-        * a
-        * ('All' | 'Once' (a))
-        * ('All' | 'Once' ('Pattern' a))
-
-    to catch regex construction __errors__, precompile 'Regex' with 'makeRegexM' or 'makeRegexOptM'
-
-    * repl:  b: 'String' | 'ByteString'
-
-        * ('Replacement' b)
-        * ('GroupReplacer' b)
-        * ('All' | 'Once' ('Replacement' b))
-        * ('All' | 'Once' ('GroupReplacer' b))
-
-    * body: b: 'String' | 'ByteString'
-
-        * b
-        * 'Body' b
-        * ('All' | 'Once' (b))
-
-    * out:
-
-        * 'String' | 'ByteString'
-    -}
-class Replace pat repl body out where
-    replace::pat -> repl -> body -> out
-
-
-instance (T.Regex a, Hint all, Replace' all a repl b) =>
-    Replace (all (Pattern a)) (repl b) (Body b) b where
-    replace = replace'
-{- ^ full typed arg
-
-    >>> replace (Once (Pattern "^a\\s")) (Replacement "A") (Body "a bc")    -}
-
-
-instance (T.Regex a, Hint all, Replace' all a repl b, Functor all) =>
-    Replace (all a) (repl b) b b where
-    replace p0 r0 b0 = replace' (Pattern <$> p0) r0 $ Body b0
-{- ^ hint 'Pattern'
-
-    >>> replace (Once "^a\\s") (Replacement "A") "a bc"     -}
-
-
-instance (T.Regex a, Hint all, Replace' all a repl b) =>
-    Replace a (all(repl b)) b b where
-    replace p0 r0 b0 = replace' p1 (unhint r0) $ Body b0
-        where p1 = swap r0 $ Pattern p0
-{- ^ hint repl
-
-    >>> replace "^a\\s" (Once (Replacement "A")) "a bc"   -}
-
-
-instance (T.Regex a, Replace' Once a repl b) =>
-    Replace a (repl b) (Once b) b where
-    replace p0 r0 b0 = replace' p1 r0 $ Body $ unhint b0
-        where p1 = swap b0 $ Pattern p0
-{- ^ hint 'Body'
-
-    >>> replace "^a\\s" (Replacement "A") $ Once "a bc"   -}
-
-
-instance (T.Regex a, Replace' All a repl b) =>
-    Replace a (repl b) (All b) b where
-    replace p0 r0 b0 = replace' p1 r0 $ Body $ unhint b0
-        where p1 = swap b0 $ Pattern p0
--- ^ hint 'Body'
-
-
-{- | internal class & instances
-
-    use 'replace' instead  -}
-class Replace' all a repl b where
-    replace'::all (Pattern a) -> repl b -> Body b -> b
-
-
-type Repl_ f rx r a = (T.Regex rx,
-                        R.RegexLike R.Regex a,
-                        Extract' a,
-                        O.ReplaceOpen f r)
-
-replace_ fn0 p0 r0 b0 =
-   let ma1 = fn0 p1 b0
-       p1 = T.makeRegex' <$> p0
-   in O.replace ma1 r0 b0
-
-
-
-instance Repl_ Maybe a repl b => Replace' Once a repl b where
-    replace' = replace_ marray_
-
-{- ^ === static replace for simple (no group) needle
-
-    for no-regex 'ByteString' replacement see "Text.Regex.Do.Split"
-
-    >>> replace (Once (Pattern "^a\\s")) (Replacement "A") (Body "a bc")
-
-    \"Abc\"
-
-   === dynamic group replace
-
-    >>> replace (Once (Pattern "\\w=(\\d{1,3})")) replacer $ Body "a=101 b=3 12"
-
-     "a=[1 0 1] b=3 12"     -}
-
-
-instance Repl_ [] a repl b => Replace' All a repl b where
-    replace' = replace_ marray_
-
-
-{- ^ to tweak regex with 'O.Comp' or 'O.Exec', see "Text.Regex.Do.Type.Regex"
-
-   === dynamic group replace
-
-   custom replacer fn returns replacement value. See 'O.defaultReplacer'
-
-   >>> replacer::GroupReplacer String
-       replacer = defaultReplacer 1 tweak1
-             where tweak1 str1 = case str1 of
-                                   "101" -> "[1 0 1]"
-                                   "3" -> "[ 3 ]"
-                                   otherwise -> trace str1 "?"
-
-
-    >>> replace (All (Pattern "\\w=(\\d{1,3})")) replacer $ Body "a=101 b=3 12"
-
-        "a=[1 0 1] b=[ 3 ] 12"      -}
-
-dum_::Comp
-dum_ = Blank
diff --git a/src/Text/Regex/Do/Pcre/Matchf.hs b/src/Text/Regex/Do/Pcre/Matchf.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Pcre/Matchf.hs
+++ /dev/null
@@ -1,39 +0,0 @@
--- | __internal__ module, exposed only to show the instances
-module Text.Regex.Do.Pcre.Matchf where
-
-import Text.Regex.Do.Type.Do
-import Text.Regex.Do.Type.Reexport as R
-import Text.Regex.Do.Result as R
-import Text.Regex.Base.RegexLike as R
-import Text.Regex.Do.Type.MatchHint
-
-type R_ b = R.RegexLike R.Regex b
-
-
-class Matchf hint b where
-    type H hint
-    type P hint
-    marray_::R_ b => hint (Pattern R.Regex) -> Body b -> H hint
-    poslen_::R_ b => hint (Pattern R.Regex) -> Body b -> P hint
-
-instance Matchf Once b where
-    type H Once = Maybe MatchArray
-    type P Once = Maybe [PosLen]
-    marray_ (Once (Pattern p0)) (Body b0) = R.matchOnce p0 b0
-    poslen_ r0 b0 = R.poslen $ marray_ r0 b0
-
-instance Matchf All b where
-    type H All = [MatchArray]
-    type P All = [[PosLen]]
-    marray_ (All (Pattern p0)) (Body b0) = R.matchAll p0 b0
-    poslen_ r0 b0 = R.poslen $ marray_ r0 b0
-
-
-once::(R_ b, R.Extract b) =>
-    Pattern R.Regex -> Body b -> [b]      -- ^ matched content
-once p0 b0 = maybe [] id $ R.allMatches b0 $ marray_ (Once p0) b0
-
-
-all::(R_ b, R.Extract b) =>
-    Pattern R.Regex -> Body b -> [[b]]       -- ^ matched content
-all p0 b0 = R.allMatches b0 $ marray_ (All p0) b0
diff --git a/src/Text/Regex/Do/Pcre/Option.hs b/src/Text/Regex/Do/Pcre/Option.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Pcre/Option.hs
+++ /dev/null
@@ -1,143 +0,0 @@
-module Text.Regex.Do.Pcre.Option (
-      Comp(..),
-      Exec(..),
-      comp,
-      exec
-   ) where
-
-import Data.Bits
-import qualified Text.Regex.PCRE.ByteString as B
-
-
--- | <http://www.pcre.org/pcre.txt pcre man pages>
-
-data Comp = Blank       {- ^ 'B.compBlank'
-
-                            clears default options: extended,caseSensitive,multiline regex
-                        -}
-
-            | Anchored  {- ^ 'B.compAnchored'
-
-            the pattern is forced to be "anchored", that is, it
-       is  constrained to match only at the first matching point in the string
-       that is being searched (the "subject string").
-
-       This effect can also  be achieved  by appropriate constructs in the pattern itself. -}
-
-            | Caseless  {- ^ 'B.compCaseless'
-
-            letters in the pattern match both upper  and  lower case  letters.
-
-            It  is  equivalent  to  Perl's /i option, and it can be changed within a pattern by a (?i) option setting.
-
-       In UTF-8 mode,  PCRE always  understands the concept of case for characters whose values are
-       less than 128, so caseless matching is always possible. For  characters with  higher  values,  the concept of case is supported if PCRE is compiled with Unicode property support.
-        If you want  to use  caseless  matching  for  characters 128 and above, you must ensure
-       that PCRE is compiled with Unicode property support  as  well  as  with UTF-8 support.   -}
-
-            | Dotall    {- ^ 'B.compDotAll'
-
-            a dot metacharacter in the pattern matches a  character of any value,
-            including one that indicates a newline.
-
-            However, it only ever matches one character, even if newlines are  coded  as  CRLF.
-
-       Without  this option, a dot does not match when the current position is
-       at a newline.
-
-       This option is equivalent to Perl's /s option, and it can be  changed within a pattern by a (?s) option setting.
-
-       A negative class such as [^a] always matches newline characters, independent of the setting of this option. -}
-
-            | Multiline {- ^ 'B.compMultiline'
-
-            By default, for the purposes of matching "start of line"  and  "end  of
-       line", PCRE treats the subject string as consisting of a single line of
-       characters, even if it actually contains newlines. The "start of  line"
-       metacharacter (^) matches only at the start of the string, and the "end
-       of line" metacharacter ($) matches only at the end of  the  string,  or
-       before  a terminating newline (except when PCRE_DOLLAR_ENDONLY is set).
-       Note, however, that unless PCRE_DOTALL  is  set,  the  "any  character"
-       metacharacter  (.)  does not match at a newline. This behaviour (for ^,
-       $, and dot) is the same as Perl.
-
-       When PCRE_MULTILINE it is set, the "start of line" and  "end  of  line"
-       constructs  match  immediately following or immediately before internal
-       newlines in the subject string, respectively, as well as  at  the  very
-       start  and  end.
-
-       This is equivalent to Perl's /m option, and it can be
-       changed within a pattern by a (?m) option setting.
-
-       If there are no newlines  in  a  subject string, or no occurrences of ^ or $ in a pattern,
-       setting PCRE_MULTILINE has no effect.    -}
-
-            | Utf8      {- ^ 'B.compUTF8'
-
-            This option causes PCRE to regard both the pattern and the  subject  as
-       strings of UTF-8 characters instead of single-byte strings. However, it
-       is available only when PCRE is built to include UTF  support.  If  not,
-       the  use  of  this option provokes an error. Details of how this option
-       changes the behaviour of PCRE are given in the pcreunicode page.     -}
-
-            | Ungreedy  {- ^ 'B.compUngreedy'
-
-            This  option  inverts  the "greediness" of the quantifiers so that they
-       are not greedy by default, but become greedy if followed by "?".
-
-       It can also be set by a (?U) option setting within the pattern.  -}
-   deriving (Eq,Ord,Enum)
-
-
-data Exec = BlankE  {- ^ 'B.execBlank'
-
-                    clears default options: extended,caseSensitive,multiline regex      -}
-            | NotEmpty  {- ^ 'B.execNotEmpty'
-
-            An empty string is not considered to be a valid match if this option is
-       set. If there are alternatives in the pattern, they are tried.  If  all
-       the  alternatives  match  the empty string, the entire match fails. For
-       example, if the pattern
-
-         a?b?
-
-       is applied to a string not beginning with "a" or  "b",  it  matches  an
-       empty  string at the start of the subject. With PCRE_NOTEMPTY set, this
-       match is not valid, so PCRE searches further into the string for occurrences of "a" or "b".        -}
-
-            | Partial   {- ^ 'B.execPartial'
-
-            see PCREPARTIAL(3)  in <http://www.pcre.org/pcre.txt pcre man pages>    -}
-   deriving (Eq,Ord,Enum)
-
-
-compOpt::Comp -> B.CompOption
-compOpt o = case o of
-   Blank -> B.compBlank
-   Anchored -> B.compAnchored
-   Caseless -> B.compCaseless
-   Dotall -> B.compDotAll
-   Multiline -> B.compMultiline
-   Utf8 -> B.compUTF8
-   Ungreedy -> B.compUngreedy
-
-
-comp::[Comp] -> B.CompOption
-comp [] = B.compBlank
-comp l = foldl (.&.) o0 l1
-   where l1 = compOpt <$> l
-         o0 = compOpt $ head l
-
-
-execOpt::Exec -> B.ExecOption
-execOpt o =   case o of
-   BlankE -> B.execBlank
-   NotEmpty -> B.execNotEmpty
-   Partial -> B.execPartial
-
-
-exec::[Exec] -> B.ExecOption
-exec [] = B.execBlank
-exec l = foldl (.&.) o0 l1
-   where l1 = execOpt <$> l
-         o0 = execOpt $ head l
diff --git a/src/Text/Regex/Do/Pcre/Utf8/Match.hs b/src/Text/Regex/Do/Pcre/Utf8/Match.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Pcre/Utf8/Match.hs
+++ /dev/null
@@ -1,99 +0,0 @@
-{- | see "Text.Regex.Base.RegexLike" and "Text.Regex.Do.Pcre.Utf8.MatchHint"
-
-    similar to "Text.Regex.Do.Pcre.Ascii.Match"
-
-    'Pattern' & 'Body' are wrapped in 'Utf8_' encoding tag.
-    This tag adds clarity, prevents calling Ascii functions by mistake.
-
-    __'toByteString''__ converts String to 'Utf8_' 'ByteString'     -}
-module Text.Regex.Do.Pcre.Utf8.Match
-    (Match(..),
-    (=~),
-    R.extract   -- | 'extract' is reexport from "Text.Regex.Base.RegexLike"
-    ) where
-
-import Text.Regex.Do.Type.Reexport as R
-import qualified Text.Regex.Base.RegexLike as R hiding (makeRegex)
-import Text.Regex.Do.Type.Do
-import Text.Regex.Do.Pcre.Matchf as F
-import Text.Regex.PCRE.Wrap()
-import Text.Regex.Do.Type.Regex as T
-import Text.Regex.Do.Type.MatchHint
-import Text.Regex.Do.Pcre.Option
-import Text.Regex.Do.Convert
-import Data.ByteString
-
-
--- | synonym for 'match'. arg without newtypes
-(=~)::Match Utf8_ a b out =>
-    a     -- ^ pattern
-    -> b    -- ^ body
-    -> out
-(=~) p0 b0 = match (Pattern $ Utf8_ p0) (Body $ Utf8_ b0)
-
-
-
-{- | * enc: 'Utf8_'
-    * a:  'String', 'ByteString', 'Regex'
-
-    to catch regex construction __errors__, precompile 'Regex' with 'makeRegexM' or 'makeRegexOptM'
-
-    * b:  'String', 'ByteString'
-    * out:
-
-        * ['String'], [['String']]
-        * ['ByteString'], [['ByteString']]
-        * 'Bool'
-        * ['PosLen'], [['PosLen']]      -}
-
-class Match enc a b out where
-    match::Pattern (enc a) -> Body (enc b) -> out
-
-
-{- | match once
-
-    ==== precompiled regex as pattern
-
- >>> let rx1 = makeRegexOpt' (Pattern $ toByteString' "左") [] []      --  add options as needed
-         rx2 = Utf8_ <$> rx1
-         m1 = U.match rx2 (Body $ toByteString' "100メートル左折後、左")::[ByteString]
-      m1 `shouldBe` [toByteString "左"]        -}
-
-instance Rx_ a b => Match Utf8_ a b [b] where
-    match p0 b0 = once (mr_ p0) $ val <$> b0
-
-
-
-instance Rx_ a b => Match Utf8_ a b Bool where
-    match p0 (Body b0) = R.matchTest (makeRegexOpt p0 [Utf8] []) $ val b0
-{- ^ test. Note that a and b may be different types e.g. 'ByteString' and 'String'
-
-    >>>  toByteString "в" =~ ("тихо в лесу"::String)::Bool
-
-    True        -}
-
--- | match all
-instance Rx_ a b => Match Utf8_ a b [[b]] where
-    match p0 b0 = F.all (mr_ p0) $ val <$> b0
-{- ^  >>> ("well"::String) =~ ("all is well that ends well"::String)::[[String]]
-
-     \[["well"\],\["well"\]]        -}
-
--- | match once
-instance Rx_ a b => Match Utf8_ a b [PosLen] where
-    match p0 b0 = maybe [] id $ poslen_ (Once $ mr_ p0) $ val <$> b0
-{- ^ >>> ("и"::String) =~ ("бывает и хуже"::String)::[PosLen]
-
-     \[(13,2)\]     -}
-
--- | match all
-instance Rx_ a b => Match Utf8_ a b [[PosLen]] where
-    match p0 b0 = poslen_ (All $ mr_ p0) $ val <$> b0
-
-
-mr_::T.Regex a => Pattern a -> Pattern R.Regex
-mr_ p0 = makeRegexOpt' p0 [Utf8] []
-
-
-dum_::String -> Utf8_ ByteString
-dum_ = toByteString'
diff --git a/src/Text/Regex/Do/Pcre/Utf8/MatchHint.hs b/src/Text/Regex/Do/Pcre/Utf8/MatchHint.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Pcre/Utf8/MatchHint.hs
+++ /dev/null
@@ -1,75 +0,0 @@
--- | see "Text.Regex.Do.Pcre.Ascii.MatchHint" about MatchHint vs Match
-
-
-module Text.Regex.Do.Pcre.Utf8.MatchHint
-    (MatchHint(..),
-    (=~)) where
-
-import Text.Regex.Do.Type.Do hiding (Once,All)
-import Text.Regex.PCRE.Wrap()
-import qualified Text.Regex.Do.Pcre.Utf8.Match as M
-import Text.Regex.Do.Type.MatchHint
-import Data.ByteString
-
-
-{- | * hint: 'Once', 'All', 'Test', 'PosLen'', 'PosLen_'
-    * a: 'String', 'ByteString'
-    * enc: 'Utf8_'
--}
-
-class (Hint hint, M.Match enc a a (F hint a)) =>
-    MatchHint hint enc a where
-    type F hint a
-    match::hint (Pattern (enc a)) -> Body (enc a) -> F hint a
-    match h0 = M.match $ unhint h0
-
-
-(=~)::MatchHint hint Utf8_ a =>
-    hint a              -- ^ hint pattern
-        -> a            -- ^ body
-        -> F hint a     -- ^ type defined by the instance, determined by the hint
-(=~) h0 = (M.=~) $ unhint h0
-
-
-instance MatchHint Test Utf8_ String where
-    type F Test String = Bool
-
-
-instance MatchHint PosLen' Utf8_ String where
-    type F PosLen' String = [PosLen]
-
-{- ^ >>> PosLen' ("и"::String) =~ "бывает и хуже"
-
-    \[(13,2)\]      -}
-
-instance MatchHint PosLen_ Utf8_ String where
-    type F PosLen_ String = [[PosLen]]
-
-instance MatchHint Once Utf8_ String where
-    type F Once String = [String]
-
-{- ^ >>> Once ("^all"::String) =~ "all the time"
-
-    \["all"\]       -}
-
-instance MatchHint All Utf8_ String where
-    type F All String = [[String]]
-
-instance MatchHint Test Utf8_ ByteString where
-    type F Test ByteString = Bool
-
-{- ^ >>> Test (toByteString "в") =~ toByteString "тихо в лесу"
-
-    True    -}
-
-instance MatchHint PosLen' Utf8_ ByteString where
-    type F PosLen' ByteString = [PosLen]
-
-instance MatchHint PosLen_ Utf8_ ByteString where
-    type F PosLen_ ByteString = [[PosLen]]
-
-instance MatchHint Once Utf8_ ByteString where
-    type F Once ByteString = [ByteString]
-
-instance MatchHint All Utf8_ ByteString where
-    type F All ByteString = [[ByteString]]
diff --git a/src/Text/Regex/Do/Pcre/Utf8/Replace.hs b/src/Text/Regex/Do/Pcre/Utf8/Replace.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Pcre/Utf8/Replace.hs
+++ /dev/null
@@ -1,180 +0,0 @@
-{- | see also "Text.Regex.Do.Pcre.Ascii.Replace"
-
-    'Pattern' & 'Body' are wrapped in 'Utf8_' encoding tag.
-    This tag adds clarity, prevents calling Ascii functions by mistake.
-
-    __'toByteString''__ converts String to 'Utf8_' 'ByteString'     -}
-
-module Text.Regex.Do.Pcre.Utf8.Replace
-    (Replace(..),
-    Replace'())  where
-
-import Prelude as P
-import Text.Regex.Do.Type.Do
-import Text.Regex.Do.Pcre.Matchf
-import qualified Text.Regex.Do.ReplaceOpen as O
-import Text.Regex.Do.Type.Regex as T
-import Text.Regex.Do.Type.MatchHint
-import Text.Regex.Do.Convert
-import Data.ByteString
-
-{- | see "Text.Regex.Do.Pcre.Ascii.Replace" for implemented types
-
-    to catch regex construction __errors__, precompile 'Regex' with 'makeRegexM' or 'makeRegexOptM'
-
-    in full typed instance every b is wrapped in 'Utf8_' newtype
-
-    'GroupReplacer' is implemented only for 'ByteString'    -}
-
-class Replace pat repl body out where
-    replace::pat -> repl -> body -> out
-
-
-instance (Replace' all enc b repl) =>
-    Replace (all (Pattern (enc b))) (repl (enc b)) (Body (enc b)) b where
-    replace = replace'
-{- ^ full typed arg
-
-    >>> replace (Once $ Pattern $ Utf8_ "праздник")
-            (Replacement $ Utf8_ "радость")
-            (Body $ Utf8_ "экзамен - всегда праздник")
--}
-
-
-instance (T.Regex b, Hint all,
-        Replace' all Utf8_ b repl,
-        Functor all,
-        Enc' repl Utf8_) =>
-    Replace (all b) (repl b) b b where
-    replace p0 r0 b0 = replace' p1 (enc' r0) $
-            Body $ Utf8_ b0
-            where p1 = Pattern  . Utf8_ <$> p0
-{- ^ hint 'Pattern'
-
-    >>> replace (All "праздник")
-            (Replacement "радость")
-            "экзамен - всегда праздник"
-    -}
-
-
-instance (T.Regex b, Hint all,
-        Replace' all Utf8_ b repl,
-        Functor all,
-        Enc' repl Utf8_) =>
-    Replace b (all (repl b)) b b where
-    replace p0 r0 b0 = replace' p1 (enc' $ unhint r0) $
-            Body $ Utf8_ b0
-        where p1 = swap r0 $ Pattern $ Utf8_ p0
-{- ^ hint repl
-
-    >>> replacer::GroupReplacer (ByteString)
-    replacer = defaultReplacer 1 tweak1
-          where tweak1 s1
-                    | s1 == toByteString "[команды]" = toByteString "А - Я"
-                    | s1 == toByteString "[счёт]" = toByteString "5:0"
-                    | s1 == toByteString "[какая боль, ]" = empty
-                    | otherwise = traceShow s1 $ toByteString "?"
-
-    >>> let rx1 = toByteString "(\\[[^\\]]+\\])"
-            body1 = toByteString "[какая боль, ][команды] : [счёт]"
-        in replace rx1 (All replacer) body1
-
-    "А - Я : 5:0"       -}
-
-instance (T.Regex b,
-        Replace' Once Utf8_ b repl,
-        Enc' repl Utf8_) =>
-    Replace b (repl b) (Once b) b where
-    replace p0 r0 b0 = replace' p1 (enc' r0) $
-            Body $ Utf8_ $ unhint b0
-        where p1 = swap b0 $ Pattern $ Utf8_ p0
-{- ^ hint 'Body'
-
-    >>> replace "праздник"
-            (Replacement "радость")
-            (Once "экзамен - всегда праздник")
-    -}
-
-
-instance (T.Regex b,
-        Replace' All Utf8_ b repl,
-        Enc' repl Utf8_) =>
-    Replace b (repl b) (All b) b where
-    replace p0 r0 b0 = replace' p1 (enc' r0) $
-            Body $ Utf8_ $ unhint b0
-        where p1 = swap b0 $ Pattern $ Utf8_ p0
-{- ^ hint 'Body'
-
-    >>> replace "праздник"
-            (Replacement "радость")
-            (All "экзамен - всегда праздник")
-    -}
-
-
-
-{- | internal class & instances
-
-    use 'replace' instead  -}
-class Replace' all enc a repl where
-    replace'::all (Pattern (enc a)) -> repl (enc a) -> Body (enc a) -> a
-
-
-instance Replace' Once Utf8_ String Replacement where
-    replace' = replace_str marray_
-
-instance Replace' All Utf8_ String Replacement where
-    replace' = replace_str marray_
-
-replace_str f0 p0 r0 b0 =
-   let ma1 = f0 p1 b1
-       b1 = toByteString . val <$> b0
-       r1 = toByteString <$> (val <$> r0)
-       p1 = T.makeRegex' . (toByteString' . val <$>) <$> p0
-   in toString $ O.replace ma1 r1 b1
-
-
-instance Replace' Once Utf8_ ByteString Replacement where
-    replace' = replace_bs marray_
-
-instance Replace' All Utf8_ ByteString Replacement where
-    replace' = replace_bs marray_
-
-replace_bs f0 p0 r0 b0 =
-   let ma1 = f0 p1 b1
-       b1 = val <$> b0
-       p1 = T.makeRegex' . (Utf8_ . val <$>) <$> p0
-   in O.replace ma1 (val <$> r0) b1
-
-
-
-instance Replace' Once Utf8_ ByteString GroupReplacer where
-    replace' = replace_bs' marray_
-
-instance Replace' All Utf8_ ByteString GroupReplacer where
-    replace' = replace_bs' marray_
-
-{- ^ >>> replacer::GroupReplacer (Utf8_ ByteString)
-         replacer = defaultReplacer 1 tweak1
-          where tweak1 bs1 = toByteString' $
-                                if bs1 == toByteString' "左" then
-                                      "ー右ー"
-                                       else "?"
-
-
-     >>> runFn1 `shouldBe` toByteString "100メートルー右ー折後、左"
-            where runFn1 =
-                     let rx1 = Pattern $ toByteString' "(?<=ル)(左)"
-                         body1 = Body $ toByteString' "100メートル左折後、左"
-                     in replace (All rx1) replacer body1        -}
-
-
-replace_bs' f0 p0 r0 b0 =
-   let ma1 = f0 p1 b1
-       b1 = val <$> b0
-       p1 = T.makeRegex' . (Utf8_ . val <$>) <$> p0
-   in O.replace ma1 (val' r0) b1
-
-
-{- ^ to tweak regex with 'Comp' or 'Exec', see "Text.Regex.Do.Type.Regex"
-
-    note 'Once_Utf8' and 'All_Utf8' hints   -}
diff --git a/src/Text/Regex/Do/Replace/Fast.hs b/src/Text/Regex/Do/Replace/Fast.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Replace/Fast.hs
@@ -0,0 +1,25 @@
+{- |  simple (no regex) fast replace on 'B.ByteString's 
+
+All occurrences are replaced. There is no Once option
+
+see 'S.replace' for detail   -}
+module Text.Regex.Do.Replace.Fast where
+
+import qualified Data.ByteString.Search as S
+import Data.ByteString as B 
+import qualified Data.ByteString.Lazy as L
+import Text.Regex.Do.Match.Matchf
+
+
+{- | >>> replace "\n" "," "a\nbc\nde"
+
+    "a,bc,de"       -}
+replace::ByteString -- ^ Pattern 
+        -> ByteString  -- ^ Replacement
+        -> ByteString   -- ^ Body
+        -> ByteString
+replace pat0
+  replacement0
+  body0 = B.concat . L.toChunks $ l
+  where l = S.replace pat1 replacement0 body0
+        !pat1 = checkPattern pat0
diff --git a/src/Text/Regex/Do/Replace/Latin.hs b/src/Text/Regex/Do/Replace/Latin.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Replace/Latin.hs
@@ -0,0 +1,84 @@
+{- | for reliable results with Utf8 pattern or body,
+    use "Text.Regex.Do.Pcre.Replace.Utf8"   -}
+
+module Text.Regex.Do.Replace.Latin
+    (Replace(..))  where
+
+import Text.Regex.Base.RegexLike as R
+import Prelude as P
+import Text.Regex.Do.Type.Do
+import Text.Regex.Do.Type.Reexport as R
+import Text.Regex.Do.Match.Matchf
+import qualified Text.Regex.Do.Replace.Open as O
+import Text.Regex.Do.Match.Regex as T
+import Text.Regex.Do.Type.Extract
+import Text.Regex.Do.Type.MatchHint
+
+
+{- | hint: 'All' | 'Once'
+
+    pattern: 'R.Regex', 'String', 'ByteString'   
+    
+    String | ByteString pattern may contains regex
+    
+    body: 'String', 'ByteString'
+
+    result is 'Either' String body: 'Left' String returns regex construction errors.   
+-} 
+class Replace hint pattern repl body out where
+    replace::(Extract' body, RegexLike R.Regex body) => 
+        hint pattern -> repl -> body -> out
+
+
+instance (R.RegexLike R.Regex b, O.Replace Maybe repl b) =>
+        Replace Once R.Regex repl b b where
+    replace (Once p0) = replace_rx p0 tagOnce
+{- ^ succeeds unless 'GroupReplacer' fails due to mismatched pattern etc 
+
+    repl: 'String' | 'ByteString' | 'GroupReplacer' repl
+-}
+
+
+instance (R.RegexLike R.Regex b, O.Replace [] repl b) =>
+        Replace All R.Regex repl b b where
+    replace (All p0) = replace_rx p0 tagAll
+{- ^ succeeds unless 'GroupReplacer' fails due to mismatched pattern etc 
+
+    repl: 'String' | 'ByteString' | 'GroupReplacer' repl
+-}
+
+
+
+instance (R.RegexLike R.Regex b, T.Regex b) => 
+    Replace Once b b b (E b) where
+    replace (Once p0) = replace_ p0 tagOnce
+{- ^ b: 'String' | 'ByteString'-}
+
+
+instance (R.RegexLike R.Regex b, T.Regex b) => 
+    Replace Once b (GroupReplacer b) b (E b) where
+    replace (Once p0) = replace_ p0 tagOnce
+{- ^ b: 'String' | 'ByteString'-}
+
+
+instance (R.RegexLike R.Regex b, T.Regex b) => 
+    Replace All b b b (E b) where
+    replace (All p0) = replace_ p0 tagAll
+{- ^ b: 'String' | 'ByteString'-}
+
+
+instance (R.RegexLike R.Regex b, T.Regex b) => 
+    Replace All b (GroupReplacer b) b (E b) where
+    replace (All p0) = replace_ p0 tagAll
+{- ^ b: 'String' | 'ByteString'-}
+
+
+replace_rx rx0 tag0 r0 b0 =
+    let Right ma1 = marray_ (Right rx0) (tag0 b0) 
+    in O.replace ma1 r0 b0
+
+
+replace_ p0 tag0 r0 b0 = 
+    marray_ (T.makeRegex p0) (tag0 b0) >>= \ma1 ->
+    Right $ O.replace ma1 r0 b0
+
diff --git a/src/Text/Regex/Do/Replace/Open.hs b/src/Text/Regex/Do/Replace/Open.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Replace/Open.hs
@@ -0,0 +1,150 @@
+{- | extensible and reusable replacement functions
+
+Run replacement with your preferred content types e.g. "Data.Text" (implemented),
+
+from search results with non-PCRE regex or non-regex libs
+
+=== how to use:    
+
+value replacement:
+
+>>> replace (Just [(4,3)::PosLen]) "4567" ("abc 123 def"::Text)
+
+"abc 4567 def"
+
+
+'GroupReplacer' : replace with a function
+
+@
+replacer::GroupReplacer Text
+replacer = defaultReplacer 1 tweak1        --  1: group 1 match. 
+          where tweak1 str1 = case str1 of
+                                "123" -> "[1-2-3]"
+                                otherwise -> traceShow str1 "?"
+@
+
+>>> replace (Just ([(4,3)]::[PosLen])) replacer ("abc 123 def"::Text)
+
+    "abc [1-2-3] def"     -}    
+
+module Text.Regex.Do.Replace.Open
+    (Replace(..),
+    defaultReplacer,
+    getGroup,
+    replaceMatch
+    )
+    where
+
+import Text.Regex.Base.RegexLike as R
+import Data.Array as A
+import Prelude as P
+import Text.Regex.Do.Type.Do
+import Text.Regex.Do.Match.Result as R
+import Text.Regex.Do.Type.Convert
+import Text.Regex.Do.Type.Extract
+
+
+
+
+class Replace f repl body where
+   replace::(Extract' body, ToArray arr) =>
+        f arr -> repl -> body -> body
+
+
+instance Replace Maybe b b where
+   replace Nothing repl0 body0 = body0
+   replace (Just ma0) repl0 body0 = firstGroup lpl1 (repl0, body0)
+        where lpl1 = A.elems $ toArray ma0
+
+
+instance Replace [] b b where
+   replace [] _ body0 = body0
+   replace ma0 repl0 body0 =
+      let lpl1 = R.poslen $ toArray <$> ma0::[[PosLen]]
+          foldFn1 lpl1 acc1 = firstGroup lpl1 (repl0,acc1)
+      in P.foldr foldFn1 body0 lpl1
+
+
+instance Replace Maybe (GroupReplacer b) b where
+   replace Nothing _ body0 = body0
+   replace (Just ma0) (GroupReplacer repl0) body0 =
+            let a1 = ReplaceAcc {
+                                  acc = body0,
+                                  pos_adj = 0
+                                }
+            in acc $ repl0 (toArray ma0) a1
+
+
+instance Replace [] (GroupReplacer b) b where
+   replace [] _ body0 = body0
+   replace ma0 (GroupReplacer repl0) body0 =
+        let acc1 = ReplaceAcc { acc = body0, pos_adj = 0 }
+        in acc $ P.foldl (flip repl0) acc1 $ toArray <$> ma0
+
+
+firstGroup::Extract' a =>
+    [PosLen] -> (a,a) -> a
+firstGroup (pl0:_) r1@(new0,a0) = acc $ replaceMatch pl0 (new0, acc1)
+    where acc1 = ReplaceAcc {
+                    acc = a0,
+                    pos_adj = 0
+                    }
+
+
+--  dynamic
+{- | Replaces specified (by idx) group match with value provided by (a -> a) fn.
+    Works for one common simple use case
+
+    'GroupReplacer' can also be used with multi-group regex
+
+    another custom dynamic replacer could e.g.
+    inspect all group matches before looking up a replacement.     -}
+defaultReplacer::Extract' a =>
+        Int         -- ^ group idx. 1-based
+        -> (a -> a) -- ^ (group match -> replacement) lookup
+            -> GroupReplacer a
+defaultReplacer idx0 tweak0 = GroupReplacer fn1
+    where fn1 (ma0::MatchArray) acc0 = maybe acc0 fn1 mval1
+                where pl1 = ma0 A.! idx0 :: (R.MatchOffset, R.MatchLength)
+                      mval1 = getGroup acc0 ma0 idx0
+                      fn1 str1 = replaceMatch pl1 (str2, acc0)
+                                 where str2 = tweak0 str1
+
+
+{- | get group content safely:
+
+    * non-existing group idx will not error but return 'Nothing'
+    * adjust for previous replacements length
+
+    see 'defaultReplacer' source for use example
+    -}
+getGroup::R.Extract a =>
+    ReplaceAcc a -> MatchArray -> Int -> Maybe a
+getGroup acc0 ma0 idx0 = if idx0 < 1 || idx0 > P.length ma0 then Nothing     --  safety catch
+    else Just val1
+    where pl1 = ma0 A.! idx0 :: (R.MatchOffset, R.MatchLength)
+          pl2 = adjustPoslen pl1 acc0
+          val1 = extract pl2 $ acc acc0
+
+
+{- | replace group match while adjusting for previous replacements length
+
+    see 'defaultReplacer' source for use example     -}
+
+replaceMatch::Extract' a =>
+        PosLen      -- ^ replaceable, unadjusted
+        -> (a, ReplaceAcc a)  -- ^ (new val, acc passed to 'GroupReplacer')
+        -> ReplaceAcc a    -- ^ new acc
+replaceMatch pl0@(_,l0) (new0, acc0) = ReplaceAcc {
+                    acc = acc1,
+                    pos_adj = pos_adj acc0 + l1 - l0
+                    }
+     where  pl1 = adjustPoslen pl0 acc0
+            prefix1 = prefix pl1 $ acc acc0
+            suffix1 = suffix pl1 $ acc acc0
+            acc1 = concat' [prefix1, new0, suffix1]
+            l1 = len' new0
+
+
+adjustPoslen::PosLen -> ReplaceAcc a -> PosLen
+adjustPoslen (p0,l0) acc0  = (p0 + pos_adj acc0, l0)
diff --git a/src/Text/Regex/Do/Replace/Template.hs b/src/Text/Regex/Do/Replace/Template.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Replace/Template.hs
@@ -0,0 +1,149 @@
+{- | formerly /Format/
+
+    substitutes placeholder values with values from args
+    
+    in lieu of /format/ function there are 2 operators: '<' and '>': no need to remember arg order.  
+
+    ==== placeholder syntax:
+
+       * index based
+
+            { Int }
+
+       * key based
+
+            { 'String' | 'ByteString' | 'Text' }
+
+    other placeholders may be implemented with
+
+    "Text.Regex.Do.Pcre.Ascii.Replace" or "Text.Regex.Do.Pcre.Utf8.Replace"       
+    
+    to avoid clash with 'Prelude':
+    
+    @import Prelude hiding((\<),(\>))@       
+
+    or qualify '<' with alias e.g. (assuming this module is imported with F alias):
+       
+    @F.<@       -}
+
+module Text.Regex.Do.Replace.Template
+    (Template(..),
+    ReplaceOne(),
+    Formatable) where
+
+import Prelude as P hiding ((<),(>))
+import Text.Regex.Do.Replace.Fast as S (replace)
+import Text.Regex.Do.Type.Convert
+import Data.ByteString as B
+import Data.Text as T
+
+
+type Formatable a = (Template a [a], Template a [(a,a)])
+
+{- | ==== implemented a:
+
+    * 'String'
+    * 'ByteString'
+    * 'Text'      
+    
+    a: template e.g. "today is {0}"
+    
+    repl: replacement: [a] or [(a,a)]
+    -}
+class Template a repl where
+   (<)::a -> repl -> a
+   (>)::repl -> a -> a
+   (>) repl0 template0 = template0 < repl0
+   
+
+instance ReplaceOne Int a =>
+    Template a [a] where
+   (<) t0 a0 = foldr_idx foldFn_idx t0 a0
+{- ^ === index based
+     >>> ["перловка"] > "на первое {0}, на второе {0}" 
+
+     "на первое перловка, на второе перловка"
+
+     >>> "Polly {0} a {1}" < ["got","cracker"]
+
+     "Polly got a cracker"
+-}
+
+foldFn_idx::ReplaceOne k v =>
+    v -> (k, v) -> v
+foldFn_idx v0 (i0, body1) = replaceOne body1 i0 v0
+
+
+
+instance ReplaceOne a a =>
+    Template a [(a, a)] where
+   (<) = P.foldr foldFn_map
+{- ^=== key based
+     key may be {any a}
+
+     >>> "овчинка {a} не {b}" < [("a","выделки"),("b","стоит")]
+
+     "овчинка выделки не стоит"
+-}
+
+
+
+foldFn_map::ReplaceOne k v =>
+    (k, v) -> v -> v
+foldFn_map (k0, v0) body1 = replaceOne body1 k0 v0
+
+
+
+--  fold with index
+type CustomerFn a b = (a -> (Int,b) -> b)
+
+foldr_idx::CustomerFn a b -> b -> [a] -> b
+foldr_idx fn0 init1 list0 = b1
+   where i0 = P.length list0 - 1
+         (-1,b1) = P.foldr (foldFn fn0) (i0,init1) list0
+
+
+foldFn::CustomerFn a b -> a -> (Int, b) -> (Int, b)
+foldFn fn0 val0 t0@(i0, _) = (i0 - 1, b1)
+   where b1 = fn0 val0 t0
+
+
+class ReplaceOne idx a where
+    replaceOne::a -> idx -> a -> a
+
+
+instance ReplaceOne Int String where
+    replaceOne body0 k0 v0 = toString bs1
+       where pat1 = toByteString $ "{" ++ (show k0) ++ "}"
+             repl1 = toByteString v0
+             bs1 = S.replace pat1 repl1 $ toByteString body0
+
+
+instance ReplaceOne String String where
+    replaceOne body0 k0 v0 = toString bs1
+       where pat1 = toByteString $ "{" ++ k0 ++ "}"
+             repl1 = toByteString v0
+             bs1 = S.replace pat1 repl1 $ toByteString body0
+
+
+instance ReplaceOne Int ByteString where
+    replaceOne body0 k0 v0 = S.replace pat1 repl1 body0
+       where pat1 =  toByteString $ "{" ++ (show k0) ++ "}"
+             repl1 = v0
+
+
+instance ReplaceOne ByteString ByteString where
+    replaceOne body0 k0 v0 = S.replace pat1 repl1 body0
+       where pat1 = B.concat [toByteString "{", k0, toByteString "}"]
+             repl1 = v0
+
+
+
+instance ReplaceOne Int Text where
+    replaceOne body0 k0 v0 = T.replace pat1 v0 body0
+       where pat1 = T.pack $ "{" ++ (show k0) ++ "}"
+
+
+instance ReplaceOne Text Text where
+    replaceOne body0 k0 v0 = T.replace pat1 v0 body0
+       where pat1 = T.concat [T.pack "{", k0, T.pack "}"]
diff --git a/src/Text/Regex/Do/Replace/Utf8.hs b/src/Text/Regex/Do/Replace/Utf8.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Replace/Utf8.hs
@@ -0,0 +1,119 @@
+{- | see also "Text.Regex.Do.Pcre.Replace.Latin"
+
+    __'toByteString'__ converts String to 'ByteString'     -}
+
+module Text.Regex.Do.Replace.Utf8
+    (Replace(..))  where
+
+import Prelude as P
+import Text.Regex.Do.Type.Do
+import Text.Regex.Do.Match.Matchf
+import qualified Text.Regex.Do.Replace.Open as O
+import Text.Regex.Do.Match.Regex as T
+import Text.Regex.Do.Type.MatchHint
+import Text.Regex.Do.Type.Convert
+import Data.ByteString
+import Text.Regex.Do.Type.Extract
+import Text.Regex.Do.Type.Reexport as R
+import Text.Regex.Base.RegexLike as R
+import Text.Regex.Do.Match.Option
+
+
+{- | see "Text.Regex.Do.Pcre.Replace.Latin" for implemented types
+
+    'GroupReplacer' is implemented only for 'ByteString'    -}
+
+class Replace hint pattern repl body out where
+    replace::(Extract' body, RegexLike R.Regex body) =>
+        hint pattern -> repl -> body -> out
+
+
+instance Replace Once R.Regex String String String where
+    replace (Once p0) r0 b0 =    
+        let b1 = toByteString b0
+            r1 = toByteString r0 
+            Right ma1 = marray_ (Right p0) (tagOnce b1)  
+        in toString $ O.replace ma1 r1 b1
+-- ^ always succeeds
+
+instance Replace All R.Regex String String String where
+    replace (All p0) r0 b0 =
+        let b1 = toByteString b0
+            r1 = toByteString r0
+            Right ma1 = marray_ (Right p0) (tagAll b1)
+        in toString $ O.replace ma1 r1 b1
+-- ^ always succeeds
+
+
+instance O.Replace Maybe repl ByteString => 
+    Replace Once R.Regex repl ByteString ByteString where
+    replace (Once p0) r0 b0 =
+        let Right ma1 = marray_ (Right p0) (tagOnce b0)
+        in O.replace ma1 r0 b0
+{- ^ succeeds unless 'GroupReplacer' fails due to mismatched pattern etc 
+
+repl: 'ByteString' | 'GroupReplacer' 'ByteString'    
+-}
+
+
+instance O.Replace [] repl ByteString => 
+    Replace All R.Regex repl ByteString ByteString where
+    replace (All p0) r0 b0 =
+        let Right ma1 = marray_ (Right p0) (tagAll b0)
+        in O.replace ma1 r0 b0
+{- ^ succeeds unless 'GroupReplacer' fails due to mismatched pattern etc 
+
+repl: 'ByteString' | 'GroupReplacer' 'ByteString'    
+-}
+
+
+
+instance Replace Once String String String (E String) where
+    replace (Once p0) = replace_str p0 tagOnce
+
+
+instance Replace All String String String (E String) where
+    replace (All p0) = replace_str p0 tagAll 
+
+
+instance Replace Once ByteString ByteString ByteString (E ByteString) where
+    replace (Once p0) = replace_bs p0 tagOnce
+
+
+instance Replace All ByteString ByteString ByteString (E ByteString)where
+    replace (All p0) = replace_bs p0 tagAll
+
+
+instance Replace Once ByteString (GroupReplacer ByteString) ByteString (E ByteString) where
+    replace (Once p0) = replace_bs p0 tagOnce
+
+instance Replace All ByteString (GroupReplacer ByteString) ByteString (E ByteString) where
+    replace (All p0) = replace_bs p0 tagAll
+{- ^ 
+@
+replacer::GroupReplacer ByteString
+replacer = defaultReplacer 1 tweak1
+      where tweak1 bs1 = toByteString' $
+                        if bs1 == toByteString "左" then
+                              "ー右ー"
+                               else "?"
+
+
+    runFn1 \`shouldBe\` toByteString "100メートルー右ー折後、左"
+        where runFn1 = let rx1 = toByteString "(?<=ル)(左)"
+                           body1 = toByteString "100メートル左折後、左"
+                       in replace (All rx1) replacer body1    
+@    -}
+
+replace_str p0 tag0 r0 b0 =
+   let b1 = toByteString b0
+       r1 = toByteString r0
+       p1 = T.makeRegexOpt p0 [Utf8] []  
+   in marray_ p1 (tag0 b0) >>= \ma1 ->
+    Right $ toString $ O.replace ma1 r1 b1
+
+
+replace_bs p0 tag0 r0 b0 =
+        marray_ (T.makeRegexOpt p0 [Utf8] []) (tag0 b0) >>= \ma1 ->
+    Right $ O.replace ma1 r0 b0
+
diff --git a/src/Text/Regex/Do/ReplaceOpen.hs b/src/Text/Regex/Do/ReplaceOpen.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/ReplaceOpen.hs
+++ /dev/null
@@ -1,147 +0,0 @@
-{- | extensible and reusable replacement functions
-
-    Run replacement with your preferred content types e.g. "Data.Text",
-    from search results with non-PCRE regex or non-regex libs
-
-    open an issue or a PR on <https://github.com/ciez/regex-do git> to request a new 'Extract'' instance
-
-    "Data.Text" instance already works  -}
-
-module Text.Regex.Do.ReplaceOpen
-    (ReplaceOpen(..),
-    defaultReplacer,
-    getGroup,
-    replaceMatch
-    )
-    where
-
-import Text.Regex.Base.RegexLike as R
-import Data.Array as A
-import Prelude as P
-import Text.Regex.Do.Type.Do
-import Text.Regex.Do.Result as R
-import Text.Regex.Do.Convert
-import Text.Regex.Do.Type.Extract
-
-
-{- | 'Replacement':
-
-    >>> replace (Just [(4,3)::PosLen]) (Replacement "4567") (Body "abc 123 def"::Body Text)
-
-    "abc 4567 def"
-
-
-    'GroupReplacer' :
-
-    >>> replacer::GroupReplacer Text
-        replacer = defaultReplacer 1 tweak1        --  1: first match in group
-              where tweak1 str1 = case str1 of
-                                    "123" -> "[1-2-3]"
-                                    otherwise -> traceShow str1 "?"
-
-    >>> replace (Just ([(4,3),(8,2)]::[PosLen])) replacer (Body "abc 123 def"::Body Text)
-
-        "abc [1-2-3] def"     -}
-
-class ReplaceOpen f r where
-   replace::(Extract' a, ToArray arr) =>
-        f arr -> r a -> Body a -> a
-
-
-instance ReplaceOpen Maybe Replacement where
-   replace Nothing (Replacement repl0) (Body b0) = b0
-   replace (Just ma0) (Replacement repl0) (Body b0) = firstGroup lpl1 (repl0, b0)
-        where lpl1 = A.elems $ toArray ma0
-
-
-instance ReplaceOpen [] Replacement where
-   replace [] _ (Body b0) = b0
-   replace ma0 (Replacement repl0) (Body b0) =
-      let lpl1 = R.poslen $ toArray <$> ma0::[[PosLen]]
-          foldFn1 lpl1 acc1 = firstGroup lpl1 (repl0,acc1)
-      in P.foldr foldFn1 b0 lpl1
-
-
-instance ReplaceOpen Maybe GroupReplacer where
-   replace Nothing _ (Body b0) = b0
-   replace (Just ma0) (GroupReplacer repl0) (Body b0) =
-            let a1 = ReplaceAcc {
-                                  acc = b0,
-                                  pos_adj = 0
-                                }
-            in acc $ repl0 (toArray ma0) a1
-
-
-instance ReplaceOpen [] GroupReplacer where
-   replace [] _ (Body b0) = b0
-   replace ma0 (GroupReplacer repl0) (Body b0) =
-        let acc1 = ReplaceAcc { acc = b0, pos_adj = 0 }
-        in acc $ P.foldl (flip repl0) acc1 $ toArray <$> ma0
-
-
-firstGroup::Extract' a =>
-    [PosLen] -> (a,a) -> a
-firstGroup (pl0:_) r1@(new0,a0) = acc $ replaceMatch pl0 (new0, acc1)
-    where acc1 = ReplaceAcc {
-                    acc = a0,
-                    pos_adj = 0
-                    }
-
-
---  dynamic
-{- | Replaces specified (by idx) group match with tweaked value.
-    Works for one common simple use case
-
-    'GroupReplacer' can be used with complicated regex
-
-    another custom dynamic replacer could e.g.
-    inspect all group matches before looking up a replacement.     -}
-defaultReplacer::Extract' a =>
-        Int         -- ^ group idx
-        -> (a -> a) -- ^ (group match -> replacement) tweak
-            -> GroupReplacer a
-defaultReplacer idx0 tweak0 = GroupReplacer fn1
-    where fn1 (ma0::MatchArray) acc0 = maybe acc0 fn1 mval1
-                where pl1 = ma0 A.! idx0 :: (R.MatchOffset, R.MatchLength)
-                      mval1 = getGroup acc0 ma0 idx0
-                      fn1 str1 = replaceMatch pl1 (str2, acc0)
-                                 where str2 = tweak0 str1
-
-
-{- | get group content safely:
-
-    * non-existing group idx will not error but return 'Nothing'
-    * adjust for previous replacements length
-
-    see 'defaultReplacer' source for use example
-    -}
-getGroup::R.Extract a =>
-    ReplaceAcc a -> MatchArray -> Int -> Maybe a
-getGroup acc0 ma0 idx0 = if idx0 >= P.length ma0 then Nothing     --  safety catch
-    else Just val1
-    where pl1 = ma0 A.! idx0 :: (R.MatchOffset, R.MatchLength)
-          pl2 = adjustPoslen pl1 acc0
-          val1 = extract pl2 $ acc acc0
-
-
-{- | replace group match while adjusting for previous replacements length
-
-    see 'defaultReplacer' source for use example     -}
-
-replaceMatch::Extract' a =>
-        PosLen      -- ^ replaceable, unadjusted
-        -> (a, ReplaceAcc a)  -- ^ (new val, acc passed to 'GroupReplacer')
-        -> ReplaceAcc a    -- ^ new acc
-replaceMatch pl0@(_,l0) (new0, acc0) = ReplaceAcc {
-                    acc = acc1,
-                    pos_adj = pos_adj acc0 + l1 - l0
-                    }
-     where  pl1 = adjustPoslen pl0 acc0
-            prefix1 = prefix pl1 $ acc acc0
-            suffix1 = suffix pl1 $ acc acc0
-            acc1 = concat' [prefix1, new0, suffix1]
-            l1 = len' new0
-
-
-adjustPoslen::PosLen -> ReplaceAcc a -> PosLen
-adjustPoslen (p0,l0) acc0  = (p0 + pos_adj acc0, l0)
diff --git a/src/Text/Regex/Do/Result.hs b/src/Text/Regex/Do/Result.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Result.hs
+++ /dev/null
@@ -1,22 +0,0 @@
-module Text.Regex.Do.Result where
-
-import qualified Data.Array as A(elems)
-import Text.Regex.Base.RegexLike as R
-import Text.Regex.Do.Type.Do
-
--- | match offset, length
-poslen::Functor f =>
-    f MatchArray -> f [PosLen]
-poslen = (A.elems <$>)
-
-
--- | all groups
-allMatches::(Functor f, R.Extract b) =>
-    Body b -> f MatchArray -> f [b]
-allMatches hay0 results0 = groupMatch hay0 <$> results0
-
-
--- | matches for one group
-groupMatch::R.Extract b =>
-    Body b -> MatchArray -> [b]
-groupMatch (Body b0) a0 = [R.extract tuple1 b0 |  tuple1 <- A.elems a0]
diff --git a/src/Text/Regex/Do/Split.hs b/src/Text/Regex/Do/Split.hs
--- a/src/Text/Regex/Do/Split.hs
+++ b/src/Text/Regex/Do/Split.hs
@@ -1,125 +1,111 @@
 {- | see "Data.ByteString.Search" package
 
+    break, split ops on 'ByteString'
+
     regex is treated as ordinary String
+    
+    break & split are now '/', '-/', '/-' 
+    
+    replace moved to "Text.Regex.Do.Replace.Fast"
     -}
 module Text.Regex.Do.Split
-    (break,
-    replace,
-    split,
-    KeepNeedle(..)) where
+    (Split(..),
+    SplitFront(..),
+    SplitEnd(..),
+    T,L
+    ) where
 
 import qualified Data.ByteString.Search as S
-import Text.Regex.Do.Type.Do hiding (replace)
 import Data.ByteString as B hiding (break, breakEnd, split)
-import qualified Data.ByteString.Lazy as L
-import Prelude hiding (break)
+import Prelude hiding (break,(/))
+import Text.Regex.Do.Match.Matchf
 
 
-data KeepNeedle = Drop  -- ^ needle between parts disappears
-        | Front -- ^ needle sticks to front of next part
-        | End   -- ^ needle sticks to end of previous part
+-- | Break result: tuple
+type T = (B.ByteString,B.ByteString)
 
-{- | >>> replace (Pattern "\n") (Replacement ",") (Body "a\nbc\nde")
+-- | Split result: list
+type L = [B.ByteString] 
 
-    "a,bc,de"       -}
-replace::Pattern ByteString -> Replacement ByteString -> Body ByteString -> ByteString
-replace (Pattern pat0)
-  (Replacement replacement)
-  (Body b0) = B.concat . L.toChunks $ l
-  where l = S.replace pat1 replacement b0
-        !pat1 = checkPattern pat0
 
 
+{- | slices 'ByteString'. drops needle
+    
+    to avoid clash with 'Prelude':
+    
+    @import Prelude hiding((/))@       
 
--- ordinary:   a b
--- front:      a \nb
--- end:        a\n b
+    or qualify '/' with alias e.g. (assuming this module is imported with S alias):
+       
+    @S./@           
+    
+    body -> pattern -> result
+    -}
+class Split out where
+    (/)::ByteString -> ByteString -> out
 
-{- | >>> break Drop (Pattern "\n") (Body "a\nbc\nde")
 
-    ("a", "bc\\nde")
+instance Split (ByteString,ByteString) where
+    (/) body0 pat0 =  (h1,t2)
+      where (h1,t1) = S.breakOn pat1 body0
+            len1 = B.length pat1
+            t2 = B.drop len1 t1
+            !pat1 = checkPattern pat0
+{- ^  >>> "a\nbc\nde" / "\n"
 
+        ("a", "bc\\nde")    -}
 
-    >>> break Front (Pattern "\n") (Body "a\nbc\nde")
 
-    ("a", "\\nbc\\nde")
+-- | keep needle \@ front
+class SplitFront out where
+    (-/)::ByteString        
+            -> ByteString   
+            -> out
 
 
-    >>> break End (Pattern "\n") (Body "a\nbc\nde")
-
-    ("a\\n", "bc\\nde")     -}
-
-break::KeepNeedle ->
-        Pattern ByteString -> Body ByteString ->
-            (ByteString, ByteString)
-break case0 = case case0 of
-                Drop -> break'
-                Front -> breakFront
-                End -> breakEnd
-
+instance SplitFront (ByteString,ByteString) where
+    (-/) body0 pat0 = S.breakOn pat1 body0
+         where !pat1 = checkPattern pat0
+{- ^ >>> "a\nbc\nde" -/ "\n" 
 
-break'::Pattern ByteString -> Body ByteString -> (ByteString, ByteString)
-break' (Pattern pat0) (Body b0) =  (h1,t2)
-  where (h1,t1) = S.breakOn pat1 b0
-        len1 = B.length pat1
-        t2 = B.drop len1 t1
-        !pat1 = checkPattern pat0
+        ("a", "\\nbc\\nde")     -}
 
 
-breakFront::Pattern ByteString -> Body ByteString -> (ByteString, ByteString)
-breakFront (Pattern pat0)
-  (Body b0) = S.breakOn pat1 b0
-     where !pat1 = checkPattern pat0
+-- | keep needle \@ end
+class SplitEnd out where
+    (/-)::ByteString       
+            -> ByteString   
+            -> out
 
 
-breakEnd::Pattern ByteString -> Body ByteString -> (ByteString, ByteString)
-breakEnd (Pattern pat0)
-  (Body b0) = S.breakAfter pat1 b0
-     where !pat1 = checkPattern pat0
-
+instance SplitEnd (ByteString,ByteString) where
+    (/-) body0 pat0 = S.breakAfter pat1 body0
+         where !pat1 = checkPattern pat0
+{- ^ >>> "a\nbc\nde" /- "\n"  
 
+    ("a\\n", "bc\\nde")         -}
 
 
-{- | >>> split Drop (Pattern " ") (Body "a bc de")
-
-    \["a", "bc", "de"]
-
-    /space may be used/
-
-   >>> split Front (Pattern "\n") (Body "a\nbc\nde")
+instance Split [ByteString] where
+    (/) body0 pat0 = S.split pat1 body0
+         where !pat1 = checkPattern pat0
+{- ^ >>> "a bc de" / " "      -- space may be used
 
-    \["a", "\\nbc", "\\nde"]
+    \["a", "bc", "de"]      -}
 
 
-    >>> split End (Pattern "\n") (Body "a\nbc\nde")
-
-   \["a\\n", "bc\\n", "de"]     -}
+instance SplitFront [ByteString] where
+    (-/) body0 pat0 = S.splitKeepFront pat1 body0
+         where !pat1 = checkPattern pat0
+{- ^ >>> "a\nbc\nde" -/ "\n"
 
-split::KeepNeedle ->
-    Pattern ByteString -> Body ByteString ->
-        [ByteString]
-split case0 = case case0 of
-                Drop -> split'
-                Front -> splitFront
-                End -> splitEnd
+    \["a", "\\nbc", "\\nde"]        -}
 
 
-split'::Pattern ByteString -> Body ByteString -> [ByteString]
-split' (Pattern pat0)
-  (Body b0) = S.split pat1 b0
-     where !pat1 = checkPattern pat0
-
-splitEnd::Pattern ByteString -> Body ByteString -> [ByteString]
-splitEnd (Pattern pat0)
-  (Body b0) = S.splitKeepEnd pat1 b0
-     where !pat1 = checkPattern pat0
-
-splitFront::Pattern ByteString -> Body ByteString -> [ByteString]
-splitFront (Pattern pat0)
-  (Body b0) = S.splitKeepFront pat1 b0
-     where !pat1 = checkPattern pat0
+instance SplitEnd [ByteString] where
+    (/-) body0 pat0 = S.splitKeepEnd pat1 body0
+         where !pat1 = checkPattern pat0
+{- ^ >>> "a\nbc\nde" /- "\n"
 
+    \["a\\n", "bc\\n", "de"]     -}
 
-checkPattern::ByteString -> ByteString
-checkPattern bs0 = if bs0 == B.empty then error "empty pattern"
-      else bs0
diff --git a/src/Text/Regex/Do/Trim.hs b/src/Text/Regex/Do/Trim.hs
--- a/src/Text/Regex/Do/Trim.hs
+++ b/src/Text/Regex/Do/Trim.hs
@@ -1,14 +1,13 @@
 module Text.Regex.Do.Trim where
 
-import Text.Regex.Do.Type.Do
 import Data.Char(isSpace)
 import qualified Data.ByteString as B
 import qualified Data.Text as T
-import Text.Regex.Do.Convert
-import Text.Regex.Do.Pcre.Ascii.Replace
+import Text.Regex.Do.Type.Convert
+import Text.Regex.Do.Replace.Latin
 import Text.Regex.Do.Type.MatchHint
-import Text.Regex.Do.Type.Regex
-import Text.Regex.Do.Pcre.Option
+import Text.Regex.Do.Match.Regex
+import Text.Regex.Do.Match.Option
 
 
 {- | removes leading and trailing spaces and tabs   -}
@@ -18,11 +17,11 @@
 
 
 instance Trim B.ByteString where
-    trim bs1 = replace rx2 repl1 (All bs1)
-       where repl1 = Replacement B.empty
+    trim bs1 = replace (All rx3) repl1 bs1
+       where repl1 = B.empty
              rx1 = "(^[\\s\\t]+)|([\\s\\t]+$)"
-             rx2 = let p1 = Pattern $ toByteString rx1
-                        in makeRegexOpt p1 [Blank] []
+             rx2 = toByteString rx1
+             Right rx3 = makeRegexOpt rx2 [Blank] []  
 
 
 instance Trim String where
diff --git a/src/Text/Regex/Do/Type/Convert.hs b/src/Text/Regex/Do/Type/Convert.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Type/Convert.hs
@@ -0,0 +1,31 @@
+module Text.Regex.Do.Type.Convert where
+
+import qualified Data.Text.Encoding as E
+import qualified Data.Text as T
+import Data.ByteString as B
+import Text.Regex.Do.Type.Do
+import Text.Regex.Base.RegexLike as R
+import Data.Array as A
+import Prelude as P
+
+
+-- | both Ascii and Utf8
+toByteString::String -> ByteString
+toByteString = E.encodeUtf8 . T.pack
+
+
+-- | both Ascii and Utf8
+toString::ByteString -> String
+toString = T.unpack . E.decodeUtf8
+
+
+
+class ToArray a where
+    toArray::a -> MatchArray
+
+instance ToArray MatchArray where
+    toArray = id
+
+instance ToArray [PosLen] where
+    toArray [] = listArray (0,0) []
+    toArray lpl0 = listArray (1, P.length lpl0) lpl0
diff --git a/src/Text/Regex/Do/Type/Do.hs b/src/Text/Regex/Do/Type/Do.hs
--- a/src/Text/Regex/Do/Type/Do.hs
+++ b/src/Text/Regex/Do/Type/Do.hs
@@ -3,7 +3,7 @@
 import Text.Regex.Base.RegexLike as R
 
 
--- | see "Text.Regex.Do.Pcre.ReplaceOpen" 'defaultReplacer' for example implementation
+-- | see "Text.Regex.Do.Replace.Open" 'defaultReplacer' for example implementation
 newtype GroupReplacer b = GroupReplacer (MatchArray -> ReplaceAcc b -> ReplaceAcc b) -- MatchArray -> acc -> acc
 
 data ReplaceAcc b = ReplaceAcc {
@@ -16,13 +16,6 @@
 
 
 
--- | Needle
-data Pattern a = Pattern a  deriving (Functor)          -- Bs, String, RegexPcre
-instance Applicative Pattern where
-    pure p0 = Pattern p0
-    (<*>) (Pattern f0) (Pattern a0) = Pattern $ f0 a0
-
-
 -- | Haystack
 data Body b = Body b deriving (Functor)                -- Bs, String
 instance Applicative Body where
@@ -30,46 +23,9 @@
     (<*>) (Body f0) (Body a0) = Body $ f0 a0
 
 
-data Replacement r = Replacement r deriving (Functor)     --    Bs, String
-instance Applicative Replacement where
-    pure p0 = Replacement p0
-    (<*>) (Replacement f0) (Replacement a0) = Replacement $ f0 a0
-
 -- | Offset, Length
 type PosLen = (MatchOffset, MatchLength)
 
 
-
-newtype Utf8_ a = Utf8_ a       -- ^ values
-        deriving (Functor,Eq,Ord)
-
-instance Applicative Utf8_ where
-    pure p0 = Utf8_ p0
-    (<*>) (Utf8_ f0) (Utf8_ a0) = Utf8_ $ f0 a0
-
-
--- ^ does not do any codec. Plain wrap / unwrap newtype
-class Enc enc where
-    val::enc a -> a
-    enc::a -> enc a
-
--- ^ does not do any codec. Plain wrap / unwrap newtype
-class Enc' f enc where
-    val'::f (enc a) -> f a
-    enc'::f a -> f (enc a)
-
-
-instance Enc Utf8_ where
-    val (Utf8_ v0) = v0
-    enc = Utf8_
-
-
-instance Enc enc => Enc' GroupReplacer enc where
-    val' (GroupReplacer fn0) = GroupReplacer $
-        \ma1 acc1 -> val <$> (fn0 ma1 $ enc <$> acc1)
-    enc' (GroupReplacer fn0) = GroupReplacer $
-        \ma1 acc1 -> enc <$> (fn0 ma1 $ val <$> acc1)
-
-instance Enc enc => Enc' Replacement enc where
-    val' = (val <$>)
-    enc' = (enc <$>)
+{-| 'Left' String returns regex construction error -}
+type E a = Either String a
diff --git a/src/Text/Regex/Do/Type/Extract.hs b/src/Text/Regex/Do/Type/Extract.hs
--- a/src/Text/Regex/Do/Type/Extract.hs
+++ b/src/Text/Regex/Do/Type/Extract.hs
@@ -27,17 +27,6 @@
    len' = B.length
 
 
-instance Extract (Utf8_ B.ByteString) where
-    before i0 = (before i0 <$>)
-    after i0 = (after i0 <$>)
-    empty = Utf8_ R.empty
-
-
-instance Extract' (Utf8_ B.ByteString) where
-   concat' = Utf8_ . B.concat . (val <$>)
-   len' = B.length . val
-
-
 instance Extract Text where
     before = T.take
     after = T.drop
diff --git a/src/Text/Regex/Do/Type/MatchHint.hs b/src/Text/Regex/Do/Type/MatchHint.hs
--- a/src/Text/Regex/Do/Type/MatchHint.hs
+++ b/src/Text/Regex/Do/Type/MatchHint.hs
@@ -1,10 +1,10 @@
 module Text.Regex.Do.Type.MatchHint where
 
 newtype Test a = Test a     -- ^ test: does body match pattern?
-newtype Once a = Once a     -- ^ match / replace once
+newtype Once a = Once a     -- ^ replace once
         deriving (Functor)
 
-newtype All a = All a        -- ^ match / replace all
+newtype All a = All a        -- ^ replace all
         deriving (Functor)
 
 newtype PosLen' a = PosLen' a   -- ^ once
@@ -45,7 +45,3 @@
 instance Applicative All where
     pure p0 = All p0
     (<*>) (All f0) (All a0) = All $ f0 a0
-
-
-swap::Hint hint => hint a -> b -> hint b
-swap _ = hint
diff --git a/src/Text/Regex/Do/Type/Regex.hs b/src/Text/Regex/Do/Type/Regex.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Type/Regex.hs
+++ /dev/null
@@ -1,121 +0,0 @@
-module Text.Regex.Do.Type.Regex
-    (Regex(..),
-    makeRegex',
-    makeRegexOpt',
-    RegexResult(..),
-    Rx_, Opt_, Ro_) where
-
-import qualified Text.Regex.Base.RegexLike as R
-import qualified Text.Regex.Do.Type.Reexport as R
-import Data.ByteString
-import Text.Regex.Do.Type.Do
-import Text.Regex.Do.Pcre.Option
-
-
-class Regex a where
-   makeRegex::Pattern a -> R.Regex
-   makeRegexM::Monad m => Pattern a -> m R.Regex
-   makeRegexOpt::Pattern a -> [Comp] -> [Exec] -> R.Regex
-   makeRegexOptM::Monad m => Pattern a -> [Comp] -> [Exec] -> m R.Regex
-
-{- ^ monadic
-
-        * 'makeRegexM'
-        * 'makeRegexOptM'
-
-        let catch regex construction errors
-
-    for 'm' to catch errors, implement 'fail' in 'm'
-
-    default 'm' implementation: 'RegexResult'
-
-    ==== makeRegexM test case:
-
-    >>>  it "RegexResult test case" $ do
-            rx1 `shouldNotSatisfy` isok1
-            rx2 `shouldSatisfy` isok1
-        where rx1 = T.makeRegexM $ Pattern "[["::RegexResult R.Regex
-              rx2 = T.makeRegexM $ Pattern "."::RegexResult R.Regex
-              isok1 (RegexResult (Left e1)) = traceShow e1 False
-              isok1 _ = True
-
-    >>> instance Show (RegexResult R.Regex) where
-            show _ = "bon"       -}
-
-makeRegex'::Regex a => Pattern a -> Pattern R.Regex
-makeRegex' = Pattern . makeRegex
-
-makeRegexOpt'::Regex a => Pattern a -> [Comp] -> [Exec] -> Pattern R.Regex
-makeRegexOpt' p0 c0 e0 = Pattern $ makeRegexOpt p0 c0 e0
-
-
-
-instance Regex a => Regex (Utf8_ a) where
-   makeRegex p0 = makeRegexOpt (Pattern val <*> p0) [Utf8] []
-   makeRegexM p0 = makeRegexOptM (Pattern val <*> p0) [Utf8] []
-   makeRegexOpt p0 c0 e0 = makeRegexOpt (Pattern val <*> p0) (Utf8:c0) e0
-   makeRegexOptM p0 c0 e0 = makeRegexOptM (Pattern val <*> p0) (Utf8:c0) e0
-
-
-instance Regex ByteString where
-   makeRegex (Pattern p0) = R.makeRegex p0
-   makeRegexM (Pattern p0) = R.makeRegexM p0
-   makeRegexOpt = makeRegexOpts
-   makeRegexOptM = makeRegexOptsM
-
-
-instance Regex String where
-   makeRegex (Pattern p0) = R.makeRegex p0
-   makeRegexM (Pattern p0) = R.makeRegexM p0
-   makeRegexOpt = makeRegexOpts
-   makeRegexOptM = makeRegexOptsM
-
-
-instance Regex R.Regex where
-   makeRegex (Pattern p0) = p0
-   makeRegexM (Pattern p0) = pure p0
-   makeRegexOpt (Pattern p0) _ _ = p0
-   makeRegexOptM (Pattern p0) _ _ = pure p0
-
-
--- | tweak Regex with options
-makeRegexOpts::Opt_ a =>
-    Pattern a ->
-        [Comp] -> [Exec] ->
-            R.Regex
-makeRegexOpts (Pattern pat0) comp0 exec0 = rx1
-   where c1 = comp comp0
-         e1 = exec exec0
-         rx1 = R.makeRegexOpts c1 e1 pat0
-
-
-makeRegexOptsM::(Monad m, Opt_ a) =>
-    Pattern a ->
-        [Comp] -> [Exec] ->
-            m R.Regex
-makeRegexOptsM (Pattern pat0) comp0 exec0 = rx1
-   where c1 = comp comp0
-         e1 = exec exec0
-         rx1 = R.makeRegexOptsM c1 e1 pat0
-
-
-
-type Rx_ a b = (Regex a, R.Extract b, R.RegexLike R.Regex b)
-type Opt_ a = R.RegexMaker R.Regex R.CompOption R.ExecOption a
-type Ro_ rx = (Regex rx, Opt_ rx)
-
-
-{- | catches regex construction __errors__  -}
-newtype RegexResult a = RegexResult (Either [String] a) deriving (Functor)
-
-instance Applicative RegexResult where
-    pure = RegexResult . Right
-    (<*>) (RegexResult (Left e1)) (RegexResult (Left e2)) = RegexResult $ Left $ e1 ++ e2
-    (<*>) (RegexResult (Right fn0)) (RegexResult (Left e1)) = RegexResult $ Left e1
-    (<*>) (RegexResult (Left e1)) (RegexResult (Right r1)) = RegexResult $ Left e1
-    (<*>) (RegexResult (Right fn0)) (RegexResult (Right a0)) = pure $ fn0 a0
-
-instance Monad RegexResult where
-    (>>=) (RegexResult (Left e1)) fn0 = RegexResult $ Left e1
-    (>>=) (RegexResult (Right a0)) fn0 = fn0 a0
-    fail s0 = RegexResult $ Left [s0]
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -9,6 +9,7 @@
 import qualified TestRegex.TestTrim as T
 import qualified TestRegex.TestMakeRegexM as E
 
+
 main::IO()
 main = do
             F.main
@@ -16,6 +17,6 @@
             S.main
             T.main
             O.main
-            R.main
             U.main
+            R.main
             E.main
diff --git a/test/TestRegex/TestFormat.hs b/test/TestRegex/TestFormat.hs
--- a/test/TestRegex/TestFormat.hs
+++ b/test/TestRegex/TestFormat.hs
@@ -1,12 +1,13 @@
 module TestRegex.TestFormat where
 
 import Test.Hspec
-import Text.Regex.Do.Format
+import Text.Regex.Do.Replace.Template
 import Text.Regex.Do.Pad
 import Data.String
-import Text.Regex.Do.Convert
+import Text.Regex.Do.Type.Convert
 import Data.ByteString
 import Data.Text as T
+import Prelude hiding ((<),(>))
 
 
 main::IO()
@@ -23,15 +24,17 @@
 oneFormat fn0 idx0 = hspec $ do
        describe "Habase.Bin.Format" $ do
           it "list arg 0,0 repl []" $
-            format (fn0 "на первое {0}, на второе {0}") (fn0 <$> []) `shouldBe` (fn0 "на первое {0}, на второе {0}")
+            (fn0 "на первое {0}, на второе {0}") < (fn0 <$> []) `shouldBe` (fn0 "на первое {0}, на второе {0}")
           it "list arg 0,0" $
-            format (fn0 "на первое {0}, на второе {0}") [fn0 "перловка"] `shouldBe` (fn0 "на первое перловка, на второе перловка")
+            (fn0 "на первое {0}, на второе {0}") < [fn0 "перловка"] `shouldBe` (fn0 "на первое перловка, на второе перловка")
+          it "list arg 0,0  >" $
+            [fn0 "перловка"] > (fn0 "на первое {0}, на второе {0}") `shouldBe` (fn0 "на первое перловка, на второе перловка")
           it "list arg 0,1" $ do
-            format (fn0 "Polly {0} a {1}") [fn0 "gets",fn0 "cracker"] `shouldBe` (fn0 "Polly gets a cracker")
-            format (fn0 "{10} {15} {21}") (idx0 <$> [0..22]) `shouldBe` (fn0 "10 15 21")
-            format (fn0 "{ten} {пятнадцать} {vingt}") [(fn0 "ten", fn0 "10"), (fn0 "пятнадцать", fn0 "15"), (fn0 "vingt", fn0 "20")] `shouldBe` (fn0 "10 15 20")
+            (fn0 "Polly {0} a {1}") < [fn0 "gets",fn0 "cracker"] `shouldBe` (fn0 "Polly gets a cracker")
+            (fn0 "{10} {15} {21}") < (idx0 <$> [0..22]) `shouldBe` (fn0 "10 15 21")
+            (fn0 "{ten} {пятнадцать} {vingt}") < [(fn0 "ten", fn0 "10"), (fn0 "пятнадцать", fn0 "15"), (fn0 "vingt", fn0 "20")] `shouldBe` (fn0 "10 15 20")
           it "map arg" $
-            format (fn0 "овчинка {a} не {b}") [(fn0 "a", fn0 "выделки"),(fn0 "b", fn0 "стоит")] `shouldBe` (fn0 "овчинка выделки не стоит")
+            (fn0 "овчинка {a} не {b}") < [(fn0 "a", fn0 "выделки"),(fn0 "b", fn0 "стоит")] `shouldBe` (fn0 "овчинка выделки не стоит")
 
           it "pad" $ pad '-' 5 "abc" `shouldBe` "--abc"
           it "pad'" $ pad' '-' 5 "abc" `shouldBe` "abc--"
diff --git a/test/TestRegex/TestMakeRegexM.hs b/test/TestRegex/TestMakeRegexM.hs
--- a/test/TestRegex/TestMakeRegexM.hs
+++ b/test/TestRegex/TestMakeRegexM.hs
@@ -3,8 +3,7 @@
 
 import Test.Hspec
 import Text.Regex.Do.Type.Reexport as R
-import Text.Regex.Do.Type.Regex as T
-import Text.Regex.Do.Type.Do as T
+import Text.Regex.Do.Match.Regex as T
 import Debug.Trace
 
 
@@ -14,12 +13,12 @@
           it "RegexResult test case" $ do
             rx1 `shouldNotSatisfy` isok1
             rx2 `shouldSatisfy` isok1
-        where rx1 = T.makeRegexM $ Pattern "[["::RegexResult R.Regex
-              rx2 = T.makeRegexM $ Pattern "."::RegexResult R.Regex
+        where rx1 = T.makeRegex "[["::E R.Regex
+              rx2 = T.makeRegex "."::E R.Regex
 
-              isok1 (RegexResult (Left e1)) = traceShow e1 False
+              isok1 (Left e1) = traceShow e1 False
               isok1 _ = True
 
 
-instance Show (RegexResult R.Regex) where
+instance Show (R.Regex) where
     show _ = "rx"
diff --git a/test/TestRegex/TestPcre.hs b/test/TestRegex/TestPcre.hs
--- a/test/TestRegex/TestPcre.hs
+++ b/test/TestRegex/TestPcre.hs
@@ -2,46 +2,46 @@
 
 import Test.Hspec
 import Text.Regex.Do.Type.Do as M
-import Text.Regex.Do.Pcre.Ascii.Match as M
-import Text.Regex.Do.Pcre.Utf8.Match as U
-import Text.Regex.Do.Pcre.Ascii.MatchHint as S
-import Text.Regex.Do.Pcre.Utf8.MatchHint as Su
-import Text.Regex.Do.Convert
+import Text.Regex.Do.Match.Latin as M
+import Text.Regex.Do.Match.Utf8 as U
+import Text.Regex.Do.Type.Convert
 import Data.ByteString
-import Text.Regex.Do.Type.MatchHint as S
-import Text.Regex.Do.Type.Regex
+import Text.Regex.Do.Match.Regex
+import Text.Regex.Do.Match.Option
 
 
 main::IO()
 main = hspec $ describe " matchTest " $ do
-     it " ?String " $ (M.match (Pattern n) h::[String]) `shouldBe` ["d1"]
-     it " [String] " $ (M.match (Pattern n) h::[[String]]) `shouldBe` [["d1"],["d1"]]
-     it " ?ByteString " $ (M.match (Pattern $ b n) (b <$> h)::[ByteString]) `shouldBe` [b "d1"]
-     it " [ByteString] " $ (M.match (Pattern $ b n) (b <$> h)::[[ByteString]]) `shouldBe` [[b "d1"],[b "d1"]]
-     it " ша " $ S.match (Test $ Pattern ("^ша"::String)) (Body "шапка") `shouldBe` True
-     it " cd " $ S.match (Test $ Pattern ("^cd"::String)) (Body "abcde") `shouldBe` False
-     it " cd " $ S.match (PosLen' $ Pattern ("^cd"::String)) (Body "abcde") `shouldBe` []
-     it " ab " $ S.match (Test $ Pattern ("^ab"::String)) (Body "abc") `shouldBe` True
-     it "doc 1" $ Test ("в"::ByteString) S.=~ "тихо в лесу" `shouldBe` True
-     it "doc 1.2" $ Test ("chilly"::ByteString) S.=~ "it's chilly inside, chilly outside" `shouldBe` True
-     it "doc 1.3" $ Test (toByteString "в") Su.=~ toByteString "тихо в лесу" `shouldBe` True
-     it "doc 2" $ S.Once ("^all"::String) S.=~ "all the time" `shouldBe` ["all"]
-     it "doc 3" $ S.Once ("^all"::ByteString) S.=~ "all the time" `shouldBe` ["all"]
-     it "doc 4" $ S.All ("chilly"::ByteString) S.=~ "it's chilly inside, chilly outside" `shouldBe` ([["chilly"],["chilly"]])
-     it "doc 5" $ PosLen' ("и"::String) S.=~ "бывает и хуже" `shouldBe` [(13,2)]
-     it "doc 6" $ PosLen' ("à"::String) S.=~ "tourner à gauche" `shouldBe` [(8,2)]
+     it " ?String " $ (n M.~? h::E [String]) `shouldBe` (Right ["d1"])
+     it " [String] " $ (n M.~* h::E [[String]]) `shouldBe` (Right [["d1"],["d1"]])
+     it " ?ByteString " $ (b n M.~? (b h)::E [ByteString]) `shouldBe` (Right [b "d1"])
+     it " [ByteString] " $ (b n M.~* (b h)::E [[ByteString]]) `shouldBe` (Right [[b "d1"],[b "d1"]])
+     it " ша " $ ("^ша"::String) M.~? ("шапка"::String) `shouldBe` (Right True::E Bool)
+     it " cd " $ ("^cd"::String) M.~? ("abcde"::String) `shouldBe` (Right False::E Bool)
+     it " cd " $ ("^cd"::String) M.~? ("abcde"::String) `shouldBe` (Right []::E [PosLen])
+     it " ab " $ ("^ab"::String) M.~? ("abc"::String) `shouldBe` (Right True::E Bool)
+     it "doc 1" $ ("в"::String) U.~? ("тихо в лесу"::String) `shouldBe` (Right True::E Bool)
+     it "doc 1.2" $ ("chilly"::ByteString) U.~? ("it's chilly inside, chilly outside"::ByteString) `shouldBe` (Right True::E Bool)
+     it "doc 1.3" $ (toByteString "в") U.~? toByteString "тихо в лесу" `shouldBe` (Right True::E Bool)
+     it "doc 2" $ ("^all"::String) M.~? ("all the time"::String) `shouldBe` (Right ["all"]::E [String])
+     it "doc 3" $ ("^all"::ByteString) M.~? ("all the time"::ByteString) `shouldBe` (Right ["all"]::E [ByteString])
+     it "doc 4" $ ("chilly"::ByteString) M.~* ("it's chilly inside, chilly outside"::ByteString) `shouldBe` (Right [["chilly"],["chilly"]]::E [[ByteString]])
+     it "doc 5" $ ("и"::String) U.~? ("бывает и хуже"::String) `shouldBe` (Right [(13,2)]::E [PosLen])
+     it "doc 6" $ ("à"::String) U.~? ("tourner à gauche"::String) `shouldBe` (Right [(8,2)]::E [PosLen])
      it "doc 7" $ do
-        let rx1 = makeRegexOpt' (Pattern $ toByteString'"左") [] []
-            rx2 = Utf8_ <$> rx1
-            m1 = U.match rx2 (Body $ toByteString' "100メートル左折後、左")::[ByteString]
+        let Right rx1 = makeRegexOpt (toByteString "左") [Utf8] []
+            m1 = rx1 U.~? (toByteString "100メートル左折後、左")::[ByteString]
         m1 `shouldBe` [toByteString "左"]
      it "doc 8" $ do
-        let t1 = toByteString "в" U.=~ ("тихо в лесу"::String)::Bool
+        let Right t1 = ("в"::String) U.~? ("тихо в лесу"::String)::E Bool
         t1 `shouldBe` True
      it "doc 9" $ do
-        let m1 = ("well"::String) U.=~ ("all is well that ends well"::String)::[[String]]
-        m1 `shouldBe` ([["well"],["well"]]::[[String]])
+        let Right m1 = ("лес"::String) U.~* ("Залесью, залесью…"::String)::E [[String]]
+        m1 `shouldBe` ([["лес"],["лес"]]::[[String]])
+     it "doc 10" $ do
+        let Right m1 = ("^熱"::String) U.~? ("熱い午後"::String)::E [String]
+        m1 `shouldBe` ["熱"]       
 
 n = "d1"
-h = Body "abcd1efg d1hij"
+h = "abcd1efg d1hij"
 b = toByteString
diff --git a/test/TestRegex/TestReplace.hs b/test/TestRegex/TestReplace.hs
--- a/test/TestRegex/TestReplace.hs
+++ b/test/TestRegex/TestReplace.hs
@@ -4,15 +4,15 @@
 import Test.Hspec
 import Text.Regex.Do.Type.Do
 
-import Text.Regex.Do.Pcre.Ascii.Replace as R
-import qualified Text.Regex.Do.Pcre.Utf8.Replace as U
-import Text.Regex.Do.ReplaceOpen hiding (replace)
-import Text.Regex.Do.Convert
-import Data.ByteString as B
+import Text.Regex.Do.Replace.Latin as R
+import qualified Text.Regex.Do.Replace.Utf8 as U
+import Text.Regex.Do.Replace.Open hiding (replace)
+import Text.Regex.Do.Type.Convert
 import Debug.Trace
 import Text.Regex.Do.Type.MatchHint
---import Text.Regex.Do.Pcre.Option
+import Data.ByteString
 
+
 main::IO()
 main = do
    onceUtf8
@@ -26,63 +26,56 @@
        describe "Pcre.Replace doc" $ do
           it "replaceGroup 1" $ do
             replace (Once "\\w=(\\d{1,3})") replacer "a=101 b=3 12"
-                `shouldBe` "a=[сто один] b=3 12"
+                `shouldBe` (Right "a=[сто один] b=3 12"::E String)
           it "replaceGroup 2" $ do
             replace (All "\\w=(\\d{1,3})") replacer "a=101 b=3 12"
-                `shouldBe` "a=[сто один] b=[three] 12"
+                `shouldBe` (Right "a=[сто один] b=[three] 12"::E String)
           it "replace 3" $ do
-            U.replace (Once (Pattern $ Utf8_ "менее")) (Replacement $ Utf8_ $ "более") (Body $ Utf8_ "менее менее")
-                `shouldBe` "более менее"
+            U.replace (Once "менее") ("более") ("менее менее")
+                `shouldBe` (Right "более менее"::E String)
           it "replace 4" $ do
-            U.replace (All (Pattern $ Utf8_ "менее")) (Replacement $ Utf8_ $ "боле") (Body $ Utf8_ "менее менее")
-                `shouldBe` "боле боле"
+            U.replace (All "менее") ("боле") ("менее менее")
+                `shouldBe` (Right "боле боле"::E String)
           it "replace 5" $ do
-            replace (Once "^a\\s") (Replacement "A") "a bc хол.гор."
-                `shouldBe` "Abc хол.гор."
+            U.replace (Once "^a\\s") ("A") "a bc хол.гор."
+                `shouldBe` (Right "Abc хол.гор."::E String)
 
 
 onceUtf8::IO()
 onceUtf8 = hspec $ do
        describe "Pcre.Replace Once Utf8" $ do
           it "^a\\s" $ do
-            replace (Once (Pattern "^a\\s")) (Replacement "A") (Body "a bc хол.гор.") `shouldBe` "Abc хол.гор."
+            replace (Once ("^a\\s")) ("A") ("a bc хол.гор.") `shouldBe` (Right "Abc хол.гор."::E String)
           it "^b\\s" $ do
-            replace (Once (Pattern "^b\\s")) (Replacement "A") (Body "a bc хол.гор.") `shouldBe` "a bc хол.гор."
+            replace (Once ("^b\\s")) ("A") ("a bc хол.гор.") `shouldBe` (Right "a bc хол.гор."::E String)
 
 
 latinOnceAll::IO()
 latinOnceAll =  hspec $ do
          describe "Pcre.Replace" $ do
             it "Once" $ do
-               runFn1 Once `shouldBe` toByteString "a=text1 b=11 12"
+               runFn1 Once `shouldBe` (Right $ toByteString "a=text1 b=11 12"::E ByteString)
             it "All" $ do
-               runFn1 All `shouldBe` toByteString "a=text1 b=text1 12"
+               runFn1 All `shouldBe` (Right $ toByteString "a=text1 b=text1 12"::E ByteString)
             where runFn1 hint1 =
-                     let   rx1 = pattern "(?<==)(\\d{2})"
-                           body1 = Body $ toByteString haystack1
+                     let   rx1 = toByteString "(?<==)(\\d{2})"
+                           body1 = toByteString haystack1
                            haystack1 = "a=10 b=11 12"
-                           repl1  = replacement "text1"
+                           repl1  = toByteString "text1"
                      in replace (hint1 rx1) repl1 body1
 
 
-pattern::String -> Pattern ByteString
-pattern = Pattern . toByteString
 
-
-replacement::String -> Replacement ByteString
-replacement = Replacement . toByteString
-
-
 groupReplace::IO()
 groupReplace =  hspec $ do
          describe "Pcre.Replace group" $ do
             it "Once" $ do
-               runFn1 Once `shouldBe` "a=[сто один] b=3 12"
+               runFn1 Once `shouldBe` (Right "a=[сто один] b=3 12"::E String)
             it "All" $ do
-               runFn1 All `shouldBe` "a=[сто один] b=[three] 12"
+               runFn1 All `shouldBe` (Right "a=[сто один] b=[three] 12"::E String)
             where runFn1 opts1 =
-                     let   rx1 = Pattern "\\w=(\\d{1,3})"
-                           body1 = Body "a=101 b=3 12"
+                     let   rx1 = "\\w=(\\d{1,3})"
+                           body1 = "a=101 b=3 12"
                      in replace (opts1 rx1) replacer body1
 
 
diff --git a/test/TestRegex/TestReplaceOpen.hs b/test/TestRegex/TestReplaceOpen.hs
--- a/test/TestRegex/TestReplaceOpen.hs
+++ b/test/TestRegex/TestReplaceOpen.hs
@@ -2,10 +2,10 @@
 module TestRegex.TestReplaceOpen where
 
 import Test.Hspec
-import Text.Regex.Do.ReplaceOpen as O
+import Text.Regex.Do.Replace.Open as O
 import Text.Regex.Do.Type.Do
 import Data.Text
-import Text.Regex.Do.Convert()
+import Text.Regex.Do.Type.Convert()
 import Debug.Trace
 
 
@@ -13,9 +13,11 @@
 main = hspec $ do
        describe "TestRegex.TestReplaceOpen" $ do
           it "case 1" $
-            O.replace (Just [(4,3)::PosLen]) (Replacement "4567") (Body "abc 123 def"::Body Text) `shouldBe` ("abc 4567 def"::Text)
+            O.replace (Just [(4,3)::PosLen]) ("4567"::Text) ("abc 123 def"::Text) `shouldBe` ("abc 4567 def"::Text)
           it "case 2" $
-            O.replace (Just ([(4,3),(8,2)]::[PosLen])) replacer (Body "abc 123 def"::Body Text) `shouldBe` ("abc [1-2-3] def"::Text)
+            O.replace (Just [(4,3)::PosLen]) replacer ("abc 123 def"::Text) `shouldBe` ("abc [1-2-3] def"::Text)
+          it "case 3" $
+            O.replace ([[(4,3)::PosLen]]) replacer ("abc 123 def"::Text) `shouldBe` ("abc [1-2-3] def"::Text)
 
 
 replacer::GroupReplacer Text
diff --git a/test/TestRegex/TestReplaceUtf.hs b/test/TestRegex/TestReplaceUtf.hs
--- a/test/TestRegex/TestReplaceUtf.hs
+++ b/test/TestRegex/TestReplaceUtf.hs
@@ -4,10 +4,10 @@
 import Test.Hspec
 import Text.Regex.Do.Type.Do
 import Data.ByteString
-import Text.Regex.Do.Convert
-import Text.Regex.Do.Pcre.Utf8.Replace as U
+import Text.Regex.Do.Type.Convert
+import Text.Regex.Do.Replace.Utf8 as U
 import Text.Regex.Do.Type.MatchHint
-import Text.Regex.Do.ReplaceOpen
+import Text.Regex.Do.Replace.Open
 import Debug.Trace
 
 
@@ -22,24 +22,24 @@
 doc = hspec $ do
        describe "TestRegex.TestReplaceUtf doc" $ do
             it "doc 1" $
-                U.replace (All "праздник") (Replacement "радость") "экзамен - всегда праздник"
+                U.replace (All "всегда") "часто" "экзамен - всегда праздник"
                         `shouldBe` out1
             it "doc 2" $
-                U.replace "праздник" (All (Replacement "радость")) "экзамен - всегда праздник"
+                U.replace (All "всегда") "часто" "экзамен - всегда праздник"
                         `shouldBe` out1
             it "doc 3" $
-                U.replace "праздник" (Replacement "радость") (All "экзамен - всегда праздник")
+                U.replace (All "всегда") "часто" "экзамен - всегда праздник"
                         `shouldBe` out1
             it "doc 4" $
-                U.replace "праздник" (Replacement "радость") (Once "экзамен - всегда праздник")
+                U.replace (Once "всегда") "часто" "экзамен - всегда праздник"
                         `shouldBe` out1
             it "doc 2-bs" $
-                U.replace (toByteString "праздник") (All (Replacement $ toByteString "радость")) (toByteString "экзамен - всегда праздник")
-                        `shouldBe` (toByteString out1)
+                U.replace (All $ toByteString "всегда") (toByteString "часто") (toByteString "экзамен - всегда праздник")
+                        `shouldBe` (toByteString <$> out1)
             it "doc 4-2" $
-                U.replace (Once $ Pattern $ Utf8_ "праздник") (Replacement $ Utf8_ "радость") (Body $ Utf8_ "экзамен - всегда праздник")
+                U.replace (Once "всегда") "часто" "экзамен - всегда праздник"
                         `shouldBe` out1
-        where out1 = "экзамен - всегда радость"
+        where out1 = Right "экзамен - часто праздник"::E String
 
 
 
@@ -47,17 +47,17 @@
 groupReplace =  hspec $ do
        describe "TestRegex.TestReplaceUtf" $ do
             it "All" $ do
-               runFn1 `shouldBe` toByteString "100メートルー右ー折後、左"
+               runFn1 `shouldBe` (Right $ toByteString "100メートルー右ー折後、左"::E ByteString)
             where runFn1 =
-                     let rx1 = Pattern $ toByteString' "(?<=ル)(左)"
-                         body1 = Body $ toByteString' "100メートル左折後、左"
+                     let rx1 = toByteString "(?<=ル)(左)"
+                         body1 = toByteString "100メートル左折後、左"
                      in U.replace (All rx1) replacer body1
 
 
-replacer::GroupReplacer (Utf8_ ByteString)
+replacer::GroupReplacer ByteString
 replacer = defaultReplacer 1 tweak1
-      where tweak1 bs1 = toByteString' $
-                            if bs1 == toByteString' "左" then
+      where tweak1 bs1 = toByteString $
+                            if bs1 == toByteString "左" then
                                   "ー右ー"
                                   else "?"
 
@@ -66,11 +66,11 @@
 groupReplace2_ =  hspec $ do
        describe "TestRegex.TestReplaceUtf" $ do
             it "боль" $ do
-               runFn1 `shouldBe` (toByteString "А - Я : 5:0")
+               runFn1 `shouldBe` (Right $ toByteString "А - Я : 5:0"::E ByteString)
             where runFn1 =
                      let rx1 = toByteString "(\\[[^\\]]+\\])"
                          body1 = toByteString "[какая боль, ][команды] : [счёт]"
-                     in U.replace rx1 (All replacer2_) body1
+                     in U.replace (All rx1) replacer2_ body1
 
 
 replacer2_::GroupReplacer (ByteString)
diff --git a/test/TestRegex/TestSplit.hs b/test/TestRegex/TestSplit.hs
--- a/test/TestRegex/TestSplit.hs
+++ b/test/TestRegex/TestSplit.hs
@@ -1,75 +1,74 @@
 module TestRegex.TestSplit where
 
-import Prelude hiding(break)
+import Prelude hiding((/))
 import Test.Hspec
 import Control.Exception (evaluate)
-import Text.Regex.Do.Type.Do
 import Text.Regex.Do.Split as S
+import Text.Regex.Do.Replace.Fast as S
 import qualified Data.ByteString as B
-import Text.Regex.Do.Convert
+import Text.Regex.Do.Type.Convert
 
 
+
 main::IO()
 main = hspec $ do
        describe "Habase.Regex.StringSearch.Search" $ do
           it "break :" $ do
-            break Drop (Pattern ":") (Body "0123:oid:90") `shouldBe` ("0123", "oid:90")
+            "0123:oid:90"  S./ ":"  `shouldBe` (("0123", "oid:90")::S.T)
           it "break" $ do
-            break Drop (Pattern "\n") (Body "a\nbc\nde") `shouldBe` ("a", "bc\nde")
+            "a\nbc\nde" / "\n" `shouldBe` (("a", "bc\nde")::S.T)
           it "break front" $ do
-            break Front (Pattern "\n") (Body "a\nbc\nde") `shouldBe` ("a", "\nbc\nde")
+            "a\nbc\nde" -/ "\n" `shouldBe` (("a", "\nbc\nde")::S.T)
           it "break end" $ do
-            break End (Pattern "\n") (Body "a\nbc\nde") `shouldBe` ("a\n", "bc\nde")
+            "a\nbc\nde" /- "\n"  `shouldBe` (("a\n", "bc\nde")::S.T)
           it "replace" $ do
-            S.replace (Pattern "\n") (Replacement ",") (Body "a\nbc\nde") `shouldBe` "a,bc,de"
+            S.replace "\n" "," "a\nbc\nde" `shouldBe` "a,bc,de"
           it "split" $ do
-            split Drop (Pattern "\n") (Body "a\nbc\nde") `shouldBe` ["a", "bc", "de"]
+            "a\nbc\nde" / "\n" `shouldBe` (["a", "bc", "de"]::S.L)
           it "split_sp" $ do
-            split Drop (Pattern " ") (Body "a bc de") `shouldBe` ["a", "bc", "de"]
+            "a bc de" / " " `shouldBe` (["a", "bc", "de"]::S.L)
           it "split end" $ do
-            split End (Pattern "\n") (Body "a\nbc\nde") `shouldBe` ["a\n", "bc\n", "de"]
+            "a\nbc\nde" /- "\n"  `shouldBe` (["a\n", "bc\n", "de"]::S.L)
           it "split front" $ do
-            split Front (Pattern "\n") (Body "a\nbc\nde") `shouldBe` ["a", "\nbc", "\nde"]
+            "a\nbc\nde" -/ "\n"  `shouldBe` (["a", "\nbc", "\nde"]::S.L)
           it "split regex" $ do
-            split Drop (Pattern "\\s") (Body "abc de fghi ") `shouldBe` ["abc de fghi "]
+            "abc de fghi " / "\\s"  `shouldBe` (["abc de fghi "]::S.L)
 
 
        describe "StringSearch.Search zerolength" $ do
           it "break" $ do
-            evaluate (errFn1 $ break Drop) `shouldThrow` anyException
+            evaluate (body / z1::S.T) `shouldThrow` anyException
           it "break front" $ do
-            evaluate (errFn1 $ break Front) `shouldThrow` anyException
+            evaluate (body -/ z1::S.T) `shouldThrow` anyException
           it "break end" $ do
-            evaluate (errFn1 $ break End) `shouldThrow` anyException
+            evaluate (body /- z1::S.T) `shouldThrow` anyException
           it "replace" $ do
-            evaluate (S.replace (Pattern B.empty) with body) `shouldThrow` anyException
+            evaluate (S.replace B.empty with body) `shouldThrow` anyException
           it "split" $ do
-            evaluate (errFn2 $ split Drop) `shouldThrow` anyException
+            evaluate (body / z1::S.T) `shouldThrow` anyException
           it "split end" $ do
-            evaluate (errFn2 $ split End) `shouldThrow` anyException
+            evaluate (body -/ z1::S.T) `shouldThrow` anyException
           it "split front" $ do
-            evaluate (errFn2 $ split Front) `shouldThrow` anyException
+            evaluate (body -/ z1::S.T) `shouldThrow` anyException
 
        describe "StringSearch.Search break delim not found" $ do
             it "delim not found" $ do
                 break_nf `shouldBe` ( b "a\nbc\nde", B.empty)
 
-       where   pat = Pattern "\n"
-               pat_sp = Pattern " "
-               body = Body "a\nbc\nde"
-               body_sp = Body "a bc de"
-               with = Replacement ","
-               break1 = break Drop pat body
-               breakFront1 = break Front pat body
-               breakEnd1 = break End pat body
-               replace1 = S.replace pat with body
-               split1 = split Drop pat body
-               split_sp1 = split Drop pat_sp body_sp
-               splitFront1 = split Front pat body
-               splitEnd1 = split End pat body
-               errFn1 fn1 = fn1 (Pattern B.empty) body
-               errFn2 fn1 = fn1 (Pattern B.empty) body
+       where   pat = "\n"
+               pat_sp = " "
+               body = "a\nbc\nde"
+               body_sp = "a bc de"
+               with = ","
+               break1 = body / pat::S.T 
+               breakFront1 = body -/ pat::S.T
+               breakEnd1 = body /- pat::S.T
+               replace1 = S.replace pat with $ body
+               split1 = body / pat::S.L 
+               split_sp1 = body_sp / pat_sp::S.L 
+               splitFront1 = body -/ pat::S.L  
+               splitEnd1 = body /- pat::S.L  
+               z1 = B.empty
                b = toByteString
                --   break delim not found
-               pat_nf = Pattern ":"
-               break_nf = break Drop pat_nf body
+               break_nf = body / ":"  
diff --git a/test/TestRegex/TestTrim.hs b/test/TestRegex/TestTrim.hs
--- a/test/TestRegex/TestTrim.hs
+++ b/test/TestRegex/TestTrim.hs
@@ -4,7 +4,7 @@
 import Debug.Trace
 import qualified Data.Text as T (strip, pack, unpack)
 import Text.Regex.Do.Trim
-import Text.Regex.Do.Convert
+import Text.Regex.Do.Type.Convert
 
 
 main::IO()
