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.1
+version:             2.2
 synopsis:            PCRE wrapper
 description:         format, search, replace (String | ByteString) with PCRE regex. Utf8-safe
 author:              Imants Cekusins
@@ -27,10 +27,11 @@
           Text.Regex.Do.Type.Reexport
           Text.Regex.Do.Convert
           Text.Regex.Do.Pad
-          Text.Regex.Do.Pcre.MatchSame
+          Text.Regex.Do.Pcre.MatchHint
           Text.Regex.Do.Pcre.ReplaceOpen
           Text.Regex.Do.Type.Extract
           Text.Regex.Do.Type.Regex_
+          Text.Regex.Do.Type.MatchHint
   other-modules:
           Text.Regex.Do.Pcre.Matchf
           Text.Regex.Do.Pcre.Result
diff --git a/src/Text/Regex/Do/Pcre/MatchHint.hs b/src/Text/Regex/Do/Pcre/MatchHint.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Pcre/MatchHint.hs
@@ -0,0 +1,68 @@
+{- | this module uses
+    <https://cdepillabout.github.io/haskell-type-families-presentation/#/ TypeFamilies>
+    -}
+
+{-# LANGUAGE TypeFamilies #-}
+module Text.Regex.Do.Pcre.MatchHint where
+
+import Text.Regex.Do.Type.Do hiding (Once,All)
+import Text.Regex.PCRE.Wrap()
+import qualified Text.Regex.Do.Pcre.Match as M
+import Text.Regex.Do.Type.MatchHint
+import Data.ByteString
+
+
+{- | picks 'M.Match' instance where 'Pattern' and 'Body' are of the same type
+
+    'Hint' and inferrable 'Pattern' or 'Body' type determine the instance
+
+    handy when working with 'OverloadedStrings', in other cases when compiler needs a hint
+
+    >>> Once ("^all"::String) =~ "all the time"
+
+    \["all"\]
+
+    >>> PosLen' ("и"::String) =~ "бывает и хуже"
+
+    \[(13,2)\]      -}
+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
+
+    (=~)::hint a  -- ^ pattern
+            -> a          -- ^ body
+            -> F hint a        -- ^ \- in ('-~') is the minus sign
+    (=~) h0 = (M.=~) $ unhint h0
+
+
+instance MatchHint Test String where
+    type F Test String = Bool
+
+instance MatchHint PosLen' String where
+    type F PosLen' String = [PosLen]
+
+instance MatchHint PosLen_ String where
+    type F PosLen_ String = [[PosLen]]
+
+instance MatchHint Once String where
+    type F Once String = [String]
+
+instance MatchHint All String where
+    type F All String = [[String]]
+
+instance MatchHint Test ByteString where
+    type F Test ByteString = Bool
+
+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/MatchSame.hs b/src/Text/Regex/Do/Pcre/MatchSame.hs
deleted file mode 100644
--- a/src/Text/Regex/Do/Pcre/MatchSame.hs
+++ /dev/null
@@ -1,37 +0,0 @@
-module Text.Regex.Do.Pcre.MatchSame where
-
-import Text.Regex.Do.Type.Do
-import Text.Regex.PCRE.Wrap()
-import Text.Regex.Do.Pcre.Match
-import Data.ByteString
-
-
-{- | picks 'Match' instance where 'Pattern' and 'Body' are of the same type
-
-    specify either 'Pattern' or 'Body' + 'out' types
-
-    handy when working with 'OverloadedStrings'
-
-    >>> ("^all"::String) -~ "all the time"::[String]
-
-    \["all"\]     -}
-class MatchSame a out where
-    match'::Match a a out => Pattern a -> Body a -> out
-    match' = match
-    (-~)::Match a a out => a  -- ^ pattern
-                -> a          -- ^ body
-                -> out        -- ^ \- in ('-~') is the minus sign
-    (-~) = (=~)
-
-
-instance MatchSame String Bool
-instance MatchSame String [String]
-instance MatchSame String [[String]]
-instance MatchSame String [PosLen]
-instance MatchSame String [[PosLen]]
-
-instance MatchSame ByteString Bool
-instance MatchSame ByteString [ByteString]
-instance MatchSame ByteString [[ByteString]]
-instance MatchSame ByteString [PosLen]
-instance MatchSame ByteString [[PosLen]]
diff --git a/src/Text/Regex/Do/Pcre/ReplaceOpen.hs b/src/Text/Regex/Do/Pcre/ReplaceOpen.hs
--- a/src/Text/Regex/Do/Pcre/ReplaceOpen.hs
+++ b/src/Text/Regex/Do/Pcre/ReplaceOpen.hs
@@ -3,15 +3,10 @@
     Run replacement with your preferred content types e.g. "Data.Text",
     from search results with non-PCRE regex or non-regex libs
 
-    open a bug or a PR on <https://github.com/ciez/regex-do git> to request a new 'Extract'' instance
-
-    "Data.Text" instance already works
-
-    >>> replace (Just [(4,3)::PosLen]) (Replacement "4567") (Body "abc 123 def"::Body Text)
+    open an issue or a PR on <https://github.com/ciez/regex-do git> to request a new 'Extract'' instance
 
-    "abc 4567 def"
+    "Data.Text" instance already works  -}
 
-    'GroupReplacer' can be used too     -}
 module Text.Regex.Do.Pcre.ReplaceOpen
     (ReplaceOpen(..),
     defaultReplacer,
@@ -28,6 +23,25 @@
 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) =>
diff --git a/src/Text/Regex/Do/Type/MatchHint.hs b/src/Text/Regex/Do/Type/MatchHint.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Regex/Do/Type/MatchHint.hs
@@ -0,0 +1,19 @@
+module Text.Regex.Do.Type.MatchHint where
+
+
+newtype Test a = Test a
+newtype Once a = Once a     -- ^ values
+newtype All a = All a       -- ^ values
+newtype PosLen' a = PosLen' a   -- ^ once
+newtype PosLen_ a = PosLen_ a   -- ^ all
+
+
+class Hint hint where
+    unhint::hint a -> a
+
+
+instance Hint Test where unhint (Test a0) = a0
+instance Hint Once where unhint (Once a0) = a0
+instance Hint All where unhint (All a0) = a0
+instance Hint PosLen' where unhint (PosLen' a0) = a0
+instance Hint PosLen_ where unhint (PosLen_ a0) = a0
diff --git a/test/TestRegex/TestPcre.hs b/test/TestRegex/TestPcre.hs
--- a/test/TestRegex/TestPcre.hs
+++ b/test/TestRegex/TestPcre.hs
@@ -5,23 +5,25 @@
 import Text.Regex.Do.Pcre.Match as M
 import Text.Regex.Do.Convert
 import Data.ByteString
-import Text.Regex.Do.Pcre.MatchSame as M
+import Text.Regex.Do.Pcre.MatchHint as S
+import Text.Regex.Do.Type.MatchHint as S
 
+
 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 " ша " $ M.match' (Pattern ("^ша"::String)) (Body "шапка") `shouldBe` True
-     it " cd " $ M.match' (Pattern ("^cd"::String)) (Body "abcde") `shouldBe` False
-     it " cd " $ M.match' (Pattern ("^cd"::String)) (Body "abcde") `shouldBe` ([]::[PosLen])
-     it " ab " $ M.match' (Pattern ("^ab"::String)) (Body "abc") `shouldBe` True
-     it "doc 1" $ ("в"::ByteString) -~ "тихо в лесу" `shouldBe` True
-     it "doc 2" $ ("^all"::String) -~ "all the time" `shouldBe` ["all"::String]
-     it "doc 3" $ ("^all"::ByteString) -~ "all the time" `shouldBe` (["all"]::[ByteString])
-     it "doc 4" $ ("well"::ByteString) -~ "all is well that ends well" `shouldBe` ([["well"],["well"]]::[[ByteString]])
-     it "doc 5" $ ("и"::String) -~ "бывает и хуже" `shouldBe` ([(13,2)]::[PosLen])
+     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 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 ("well"::ByteString) S.=~ "all is well that ends well" `shouldBe` ([["well"],["well"]])
+     it "doc 5" $ PosLen' ("и"::String) S.=~ "бывает и хуже" `shouldBe` [(13,2)]
 
 n = "d1"
 h = Body "abcd1efg d1hij"
