diff --git a/Data/Aeson/Encoding/Builder.hs b/Data/Aeson/Encoding/Builder.hs
--- a/Data/Aeson/Encoding/Builder.hs
+++ b/Data/Aeson/Encoding/Builder.hs
@@ -44,7 +44,7 @@
 import Data.ByteString.Builder.Prim as BP
 import Data.ByteString.Builder.Scientific (scientificBuilder)
 import Data.Char (chr, ord)
-import Data.Monoid ((<>))
+import Data.Semigroup ((<>))
 import Data.Scientific (Scientific, base10Exponent, coefficient)
 import Data.Text.Encoding (encodeUtf8BuilderEscaped)
 import Data.Time (UTCTime(..))
diff --git a/Data/Aeson/Text.hs b/Data/Aeson/Text.hs
--- a/Data/Aeson/Text.hs
+++ b/Data/Aeson/Text.hs
@@ -25,7 +25,7 @@
 
 import Data.Aeson.Types (Value(..), ToJSON(..))
 import Data.Aeson.Encoding (encodingToLazyByteString)
-import Data.Monoid ((<>))
+import Data.Semigroup ((<>))
 import Data.Scientific (FPFormat(..), Scientific, base10Exponent)
 import Data.Text.Lazy.Builder
 import Data.Text.Lazy.Builder.Scientific (formatScientificBuilder)
diff --git a/Data/Aeson/Types/FromJSON.hs b/Data/Aeson/Types/FromJSON.hs
--- a/Data/Aeson/Types/FromJSON.hs
+++ b/Data/Aeson/Types/FromJSON.hs
@@ -97,7 +97,7 @@
 import Data.Int (Int16, Int32, Int64, Int8)
 import Data.List.NonEmpty (NonEmpty(..))
 import Data.Maybe (fromMaybe)
-import Data.Monoid ((<>))
+import Data.Semigroup ((<>))
 import Data.Proxy (Proxy(..))
 import Data.Ratio ((%), Ratio)
 import Data.Scientific (Scientific)
@@ -976,7 +976,7 @@
 
 instance (FromRecord arity f) => FromTaggedObject'' arity f True where
     parseFromTaggedObject'' opts fargs _ =
-      Tagged . parseRecord opts fargs Nothing
+      Tagged . parseRecord opts fargs
 
 instance (GFromJSON arity f) => FromTaggedObject'' arity f False where
     parseFromTaggedObject'' opts fargs contentsFieldName = Tagged .
@@ -993,57 +993,52 @@
 
 class ConsFromJSON' arity f isRecord where
     consParseJSON' :: Options -> FromArgs arity a
-                   -> Maybe Text -- ^ A dummy label
-                                 --   (Nothing to use proper label)
                    -> Value -> Tagged isRecord (Parser (f a))
 
 instance ( IsRecord            f isRecord
          , ConsFromJSON' arity f isRecord
          ) => ConsFromJSON arity f where
-    consParseJSON opts fargs v = let
-      (v2,lab) = case (unwrapUnaryRecords opts,isUnary (undefined :: f a)) of
-                       -- use a dummy object with a dummy label
-        (True,True) -> (object [(pack "dummy",v)], Just $ pack "dummy")
-        _ ->(v,Nothing)
-      in (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))
-                       $ consParseJSON' opts fargs lab v2
+    consParseJSON opts fargs =
+      (unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))
+        . consParseJSON' opts fargs
 
+instance OVERLAPPING_
+         ( GFromJSON arity a, FromRecord arity (S1 s a)
+         ) => ConsFromJSON' arity (S1 s a) True where
+    consParseJSON' opts fargs
+      | unwrapUnaryRecords opts = Tagged . gParseJSON opts fargs
+      | otherwise = Tagged . withObject "unary record" (parseRecord opts fargs)
 
-instance (FromRecord arity f) => ConsFromJSON' arity f True where
-    consParseJSON' opts fargs mlab = Tagged . withObject "record (:*:)"
-                                        (parseRecord opts fargs mlab)
+instance FromRecord arity f => ConsFromJSON' arity f True where
+    consParseJSON' opts fargs =
+      Tagged . withObject "record (:*:)" (parseRecord opts fargs)
 
-instance (GFromJSON arity f) => ConsFromJSON' arity f False where
-    consParseJSON' opts fargs _ = Tagged . gParseJSON opts fargs
+instance GFromJSON arity f => ConsFromJSON' arity f False where
+    consParseJSON' opts fargs = Tagged . gParseJSON opts fargs
 
 --------------------------------------------------------------------------------
 
 class FromRecord arity f where
     parseRecord :: Options -> FromArgs arity a
-                -> Maybe Text -- ^ A dummy label
-                              --   (Nothing to use proper label)
                 -> Object -> Parser (f a)
 
 instance ( FromRecord arity a
          , FromRecord arity b
          ) => FromRecord arity (a :*: b) where
-    parseRecord opts fargs _ obj =
-      (:*:) <$> parseRecord opts fargs Nothing obj
-            <*> parseRecord opts fargs Nothing obj
+    parseRecord opts fargs obj =
+      (:*:) <$> parseRecord opts fargs obj
+            <*> parseRecord opts fargs obj
 
 instance OVERLAPPABLE_ (Selector s, GFromJSON arity a) =>
   FromRecord arity (S1 s a) where
-    parseRecord opts fargs lab =
+    parseRecord opts fargs =
       (<?> Key label) . gParseJSON opts fargs <=< (.: label)
         where
-          label = fromMaybe defLabel lab
-          defLabel = pack . fieldLabelModifier opts $
-                       selName (undefined :: t s a p)
+          label = pack . fieldLabelModifier opts $ selName (undefined :: t s a p)
 
 instance INCOHERENT_ (Selector s, FromJSON a) =>
   FromRecord arity (S1 s (K1 i (Maybe a))) where
-    parseRecord _ _ (Just lab) obj = M1 . K1 <$> obj .:? lab
-    parseRecord opts _ Nothing obj = M1 . K1 <$> obj .:? pack label
+    parseRecord opts _ obj = M1 . K1 <$> obj .:? pack label
         where
           label = fieldLabelModifier opts $
                     selName (undefined :: t s (K1 i (Maybe a)) p)
@@ -1051,7 +1046,7 @@
 -- Parse an Option like a Maybe.
 instance INCOHERENT_ (Selector s, FromJSON a) =>
   FromRecord arity (S1 s (K1 i (Semigroup.Option a))) where
-    parseRecord opts fargs lab obj = wrap <$> parseRecord opts fargs lab obj
+    parseRecord opts fargs obj = wrap <$> parseRecord opts fargs obj
       where
         wrap :: S1 s (K1 i (Maybe a)) p -> S1 s (K1 i (Semigroup.Option a)) p
         wrap (M1 (K1 a)) = M1 (K1 (Semigroup.Option a))
diff --git a/Data/Aeson/Types/Generic.hs b/Data/Aeson/Types/Generic.hs
--- a/Data/Aeson/Types/Generic.hs
+++ b/Data/Aeson/Types/Generic.hs
@@ -44,12 +44,8 @@
 --------------------------------------------------------------------------------
 
 class IsRecord (f :: * -> *) isRecord | f -> isRecord
-  where
-    isUnary :: f a -> Bool
-    isUnary = const True
 
 instance (IsRecord f isRecord) => IsRecord (f :*: g) isRecord
-  where isUnary = const False
 #if MIN_VERSION_base(4,9,0)
 instance OVERLAPPING_ IsRecord (M1 S ('MetaSel 'Nothing u ss ds) f) False
 #else
@@ -61,7 +57,6 @@
 instance IsRecord (Rec1 f) True
 instance IsRecord (f :.: g) True
 instance IsRecord U1 False
-  where isUnary = const False
 
 --------------------------------------------------------------------------------
 
diff --git a/Data/Aeson/Types/ToJSON.hs b/Data/Aeson/Types/ToJSON.hs
--- a/Data/Aeson/Types/ToJSON.hs
+++ b/Data/Aeson/Types/ToJSON.hs
@@ -80,7 +80,7 @@
 import Data.Int (Int16, Int32, Int64, Int8)
 import Data.List (intersperse)
 import Data.List.NonEmpty (NonEmpty(..))
-import Data.Monoid ((<>))
+import Data.Semigroup ((<>))
 import Data.Proxy (Proxy(..))
 import Data.Ratio (Ratio, denominator, numerator)
 import Data.Scientific (Scientific)
@@ -860,7 +860,7 @@
          ) => TaggedObject enc arity (C1 c a)
   where
     taggedObject opts targs tagFieldName contentsFieldName =
-      fromPairs . (tag <>) . contents
+      fromPairs . mappend tag . contents
       where
         tag = tagFieldName `pair`
           (fromString (constructorTagModifier opts (conName (undefined :: t c a p)))
@@ -956,7 +956,6 @@
 
 class ConsToJSON' enc arity f isRecord where
     consToJSON'     :: Options -> ToArgs enc arity a
-                    -> Bool -- ^ Are we a record with one field?
                     -> f a -> Tagged isRecord enc
 
 instance ( IsRecord                f isRecord
@@ -965,23 +964,28 @@
   where
     consToJSON opts targs =
         (unTagged :: Tagged isRecord enc -> enc)
-      . consToJSON' opts targs (isUnary (undefined :: f a))
+      . consToJSON' opts targs
     {-# INLINE consToJSON #-}
 
-instance ( RecordToPairs enc pairs arity f
+instance OVERLAPPING_
+         ( RecordToPairs enc pairs arity (S1 s f)
          , FromPairs enc pairs
          , GToJSON enc arity f
-         ) => ConsToJSON' enc arity f True
+         ) => ConsToJSON' enc arity (S1 s f) True
   where
-    consToJSON' opts targs isUn =
-      Tagged .
-        case (isUn, unwrapUnaryRecords opts) of
-          (True, True) -> gToJSON opts targs
-          _ -> fromPairs . recordToPairs opts targs
+    consToJSON' opts targs
+      | unwrapUnaryRecords opts = Tagged . gToJSON opts targs
+      | otherwise = Tagged . fromPairs . recordToPairs opts targs
     {-# INLINE consToJSON' #-}
 
+instance ( RecordToPairs enc pairs arity f
+         , FromPairs enc pairs
+         ) => ConsToJSON' enc arity f True
+  where
+    consToJSON' opts targs = Tagged . fromPairs . recordToPairs opts targs
+
 instance GToJSON enc arity f => ConsToJSON' enc arity f False where
-    consToJSON' opts targs _ = Tagged . gToJSON opts targs
+    consToJSON' opts targs = Tagged . gToJSON opts targs
     {-# INLINE consToJSON' #-}
 
 --------------------------------------------------------------------------------
@@ -999,7 +1003,7 @@
          ) => RecordToPairs enc pairs arity (a :*: b)
   where
     recordToPairs opts (targs :: ToArgs enc arity p) (a :*: b) =
-        pairsOf a <> pairsOf b
+        pairsOf a `mappend` pairsOf b
       where
         pairsOf :: (RecordToPairs enc pairs arity f) => f p -> pairs
         pairsOf = recordToPairs opts targs
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -24,5 +24,4 @@
 
 # Authors
 
-This library is written and maintained by Bryan O'Sullivan,
-<bos@serpentine.com>.
+This library was originally written by Bryan O'Sullivan.
diff --git a/aeson.cabal b/aeson.cabal
--- a/aeson.cabal
+++ b/aeson.cabal
@@ -1,5 +1,5 @@
 name:            aeson
-version:         1.3.0.0
+version:         1.3.1.0
 license:         BSD3
 license-file:    LICENSE
 category:        Text, Web, JSON
@@ -21,20 +21,6 @@
     To get started, see the documentation for the @Data.Aeson@ module
     below.
     .
-    Parsing performance on a late 2013 MacBook Pro (2.6GHz Core i7),
-    running 64-bit GHC 7.10.1, for mostly-English tweets from Twitter's
-    JSON search API:
-    .
-    * 6.4 KB payloads, English: 7570 msg\/sec (47.6 MB\/sec)
-    .
-    * 14.6 KB payloads, Japanese: 3261 msg\/sec (46.6 MB\/sec)
-    .
-    Encoding performance on the same machine and data:
-    .
-    * 6.4 KB payloads, English: 22738 msg\/sec (142.9 MB\/sec)
-    .
-    * 14.6 KB payloads, Japanese: 15911 msg\/sec (227.4 MB\/sec)
-    .
     (A note on naming: in Greek mythology, Aeson was the father of Jason.)
 
 extra-source-files:
@@ -116,7 +102,7 @@
   build-depends:
     attoparsec >= 0.13.0.1,
     base >= 4.5 && < 5,
-    base-compat >= 0.9.1 && < 0.10,
+    base-compat >= 0.9.1 && < 0.11,
     containers >= 0.4.2,
     deepseq >= 1.3 && < 1.5,
     dlist >= 0.6,
diff --git a/benchmarks/aeson-benchmarks.cabal b/benchmarks/aeson-benchmarks.cabal
--- a/benchmarks/aeson-benchmarks.cabal
+++ b/benchmarks/aeson-benchmarks.cabal
@@ -30,7 +30,7 @@
     build-depends:
       attoparsec >= 0.13.0.1,
       base == 4.*,
-      base-compat >= 0.9.1 && <0.10,
+      base-compat >= 0.9.1 && <0.11,
       time-locale-compat >=0.1.1 && <0.2,
       containers,
       deepseq,
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,6 +1,11 @@
 For the latest version of this document, please see [https://github.com/bos/aeson/blob/master/changelog.md](https://github.com/bos/aeson/blob/master/changelog.md).
 
-### 1.3.0.0
+### 1.3.1.0
+
+* Fix bug in generically derived `FromJSON` instances that are using `unwrapUnaryRecords`, thanks to Xia Li-yao
+* Allow base-compat 0.10.*, thanks to Oleg Grenrus
+
+## 1.3.0.0
 
 Breaking changes:
 * `GKeyValue` has been renamed to `KeyValuePair`, thanks to Xia Li-yao
diff --git a/tests/UnitTests.hs b/tests/UnitTests.hs
--- a/tests/UnitTests.hs
+++ b/tests/UnitTests.hs
@@ -99,6 +99,7 @@
   , testCase "Show Options" showOptions
   , testGroup "SingleMaybeField" singleMaybeField
   , testCase "withEmbeddedJSON" withEmbeddedJSONTest
+  , testCase "SingleFieldCon" singleFieldCon
   ]
 
 roundTripCamel :: String -> Assertion
@@ -533,6 +534,17 @@
 withEmbeddedJSONTest :: Assertion
 withEmbeddedJSONTest =
   assertEqual "Unquote embedded JSON" (Right $ EmbeddedJSONTest 1) (eitherDecode "{\"prop\":\"1\"}")
+
+-- Regression test for https://github.com/bos/aeson/issues/627
+newtype SingleFieldCon = SingleFieldCon Int deriving (Eq, Show, Generic)
+
+instance FromJSON SingleFieldCon where
+  parseJSON = genericParseJSON defaultOptions{unwrapUnaryRecords=True}
+  -- This option should have no effect on this type
+
+singleFieldCon :: Assertion
+singleFieldCon =
+  assertEqual "fromJSON" (Right (SingleFieldCon 0)) (eitherDecode "0")
 
 deriveJSON defaultOptions{omitNothingFields=True} ''MyRecord
 
