diff --git a/src/Text/Show/Unicode.hs b/src/Text/Show/Unicode.hs
--- a/src/Text/Show/Unicode.hs
+++ b/src/Text/Show/Unicode.hs
@@ -50,9 +50,10 @@
 module Text.Show.Unicode (ushow, uprint, ushowWith, uprintWith) where
 
 import           Control.Applicative          ((<|>))
-import           Data.Char                    (isPrint)
+import           Data.Char                    (isAscii, isPrint)
 import           Text.ParserCombinators.ReadP
 import           Text.Read.Lex                (lexChar)
+import qualified Data.List                     as L
 
 -- Represents a replaced character using its literal form and its escaped form.
 type Replacement = (String, String)
@@ -63,18 +64,38 @@
 --  * Otherwise, leave the string as it was.
 --  * Note that special delimiter sequence "\&" may appear in a string. c.f.  <https://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-200002.6 Section 2.6 of the Haskell 2010 specification>.
 recoverChar :: (Char -> Bool) -> ReadP Replacement
-recoverChar p = (represent <$> gather lexChar) <|> (("\\&","\&") <$ string "\\&")
+recoverChar p = represent <$> gather lexCharAndConsumeEmpties
   where
     represent :: (String, Char) -> Replacement
     represent (o,lc)
-      | p lc      = (o, [lc])
+      -- This is too dirty a hack.
+      -- However, I couldn't think of any other way to recover the & consumed by lexChar while not needlessly increasing the number of & by mis-detecting the escape sequence.
+      | p lc      =
+        if head o /= '\\' &&
+        "\\&" `L.isSuffixOf` o
+        then (o, lc : "\\&")
+        else (o, [lc])
       | otherwise = (o, o)
 
+-- | The base library lexChar has been handling & by itself since 4.9.1.0,
+-- so consumeEmpties is a meaningless action,
+-- but it makes sense for older versions of lexChar.
+lexCharAndConsumeEmpties :: ReadP Char
+lexCharAndConsumeEmpties = lexChar <* consumeEmpties
+    where
+    -- Consumes the string "\&" repeatedly and greedily (will only produce one match)
+    consumeEmpties :: ReadP ()
+    consumeEmpties = do
+        rest <- look
+        case rest of
+            ('\\':'&':_) -> string "\\&" >> consumeEmpties
+            _ -> return ()
+
 -- | Show the input, and then replace Haskell character literals
 -- with the character it represents, for any Unicode printable characters except backslash, single and double quotation marks.
 -- If something fails, fallback to standard 'show'.
 ushow :: Show a => a -> String
-ushow = ushowWith (\c -> isPrint c && not (c `elem` ['\\', '\'','\"'] ))
+ushow = ushowWith (\c -> isPrint c && not (isAscii c))
 
 -- | A version of 'print' that uses 'ushow'.
 uprint :: Show a => a -> IO ()
@@ -89,7 +110,7 @@
     go _  []            = ""
     go _  (([],""):_)   = ""
     go _  ((rs,""):_)   = snd $ last rs
-    go _  ((_,o):[])    = o
+    go _  [(_,o)]       = o
     go pr (([],_):rest) = go pr rest
     go _  ((rs,_):rest) = let r = last rs in snd r ++ go r rest
 
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -3,17 +3,31 @@
 
 import           Test.Hspec
 import           Test.Hspec.QuickCheck
+import           Text.Read             (readMaybe)
 
 import           Text.Show.Unicode
 
-data T試6験 = Å4 { すけろく :: String} deriving (Eq, Ord, Show, Read)
-data T試7験 = String :@\& String  deriving (Eq, Ord, Show, Read)
-data T試8験 = String :＠\& String  deriving (Eq, Ord, Show, Read)
-
+newtype T試6験 = Å4 { すけろく :: String } deriving (Eq, Ord, Show, Read)
+data T試7験 = String :@\& String deriving (Eq, Ord, Show, Read)
+data T試8験 = String :＠\& String deriving (Eq, Ord, Show, Read)
+data T試9験 = String :\&＠\& String deriving (Eq, Ord, Show, Read)
+data T試10験 = String :\&\& String deriving (Eq, Ord, Show, Read)
 
 ushowTo :: Show a => a -> String -> Spec
 ushowTo f t = it ("ushow " ++ show f ++ " == " ++ t) $ t `shouldBe` ushow f
 
+-- | check `read . ushow == id` when `read . show == id`.
+-- The reason why we don't test if the show fails is that older versions may fail to read the result of the show,
+-- which cannot be handled at the library level, so we exclude it.
+-- ==> is not used because it will cause an error if there is no test case that can be executed.
+readUShowIsIdWhenOkPrelude :: (Eq a, Show a, Read a) => a -> Expectation
+readUShowIsIdWhenOkPrelude v =
+  if preludeOk
+  then ushowOk
+  else pure ()
+  where preludeOk = readMaybe (show v) == Just v
+        ushowOk = read (ushow v) `shouldBe` v
+
 spec :: Spec
 spec =
   describe "individual representations test" $ do
@@ -37,16 +51,22 @@
         \x -> read (ushow x) `shouldBe` (x :: [(Char,())])
 
       prop "read . read . ushow . ushow == id, for String" $
-        \str -> (read $ read $ ushow $ ushow str) `shouldBe` (str :: String)
+        \str -> read (read $ ushow $ ushow str) `shouldBe` (str :: String)
 
-      prop "read . ushow == id, for some crazy Unicode type" $
-        \str -> let v = Å4 str in read (ushow v) `shouldBe` v
+      prop "read . ushow == id, for some crazy Unicode type: T試6験" $
+        \str -> readUShowIsIdWhenOkPrelude $ Å4 str
 
-      prop "read . ushow == id, for some crazy Unicode type" $
-        \a b -> let v = a :@\& b in read (ushow v) `shouldBe` v
+      prop "read . ushow == id, for some crazy Unicode type: T試7験" $
+        \a b -> readUShowIsIdWhenOkPrelude $ a :@\& b
 
-      prop "read . ushow == id, for some crazy Unicode type" $
-        \a b -> let v = a :＠\& b in read (ushow v) `shouldBe` v
+      prop "read . ushow == id, for some crazy Unicode type: T試8験" $
+        \a b -> readUShowIsIdWhenOkPrelude $ a :＠\& b
+
+      prop "read . ushow == id, for some crazy Unicode type: T試9験" $
+        \a b -> readUShowIsIdWhenOkPrelude $ a :\&＠\& b
+
+      prop "read . ushow == id, for some crazy Unicode type: T試10験" $
+        \a b -> readUShowIsIdWhenOkPrelude $ a :\&\& b
 
       prop "read . ushow == id, for compound type" $
         \str -> read (ushow str) `shouldBe` (str :: Either [String] (String,String))
diff --git a/unicode-show.cabal b/unicode-show.cabal
--- a/unicode-show.cabal
+++ b/unicode-show.cabal
@@ -1,5 +1,5 @@
 name:                unicode-show
-version:             0.1.0.4
+version:             0.1.0.5
 synopsis:            print and show in unicode
 description:
             This package provides variants of 'show' and 'print' functions that does not escape non-ascii characters.
@@ -25,7 +25,7 @@
 library
   hs-source-dirs:      src
   exposed-modules:     Text.Show.Unicode
-  build-depends:       base >= 4.7 && < 5
+  build-depends:       base >= 4.8.1.0 && < 5
   default-language:    Haskell2010
 
 test-suite unicode-show-test
