diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
 # Revision history for influxdb
 
+## v1.9.0 - 2020-07-18
+
+* Fix `Ignore` and `Empty` to replace the `QueryResults` instance for `Void`. The instance has been deprecated.
+* Remove the deprecated `parseResults` method in `QueryResults`.
+* Add the `coerceDecoder` method in `QueryResults`.
+* Drop support for GHC 8.2 and older because of the use of `EmptyDataDeriving`.
+* Update doctest comments with `TypeApplications`.
+
 ## v1.8.0 - 2020-06-19
 
 This release reworked the `QueryResuls` type class. There are some breaking changes:
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2014-2015, Mitsutoshi Aoe
+Copyright (c) 2014-2020, Mitsutoshi Aoe
 
 All rights reserved.
 
diff --git a/influxdb.cabal b/influxdb.cabal
--- a/influxdb.cabal
+++ b/influxdb.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.24
 name: influxdb
-version: 1.8.0
+version: 1.9.0
 synopsis: Haskell client library for InfluxDB
 description:
   @influxdb@ is an InfluxDB client library for Haskell.
@@ -15,8 +15,6 @@
 category: Database
 build-type: Custom
 tested-with:
-  GHC == 8.0.2
-  GHC == 8.2.2
   GHC == 8.4.4
   GHC == 8.6.5
   GHC == 8.8.3
@@ -75,7 +73,7 @@
     ViewPatterns
   ghc-options: -Wall
   build-depends:
-      base >= 4.9 && < 4.15
+      base >= 4.11 && < 4.15
     , aeson >= 0.7 && < 1.6
     , attoparsec < 0.14
     , bytestring >= 0.10 && < 0.11
diff --git a/src/Database/InfluxDB.hs b/src/Database/InfluxDB.hs
--- a/src/Database/InfluxDB.hs
+++ b/src/Database/InfluxDB.hs
@@ -52,15 +52,19 @@
   , Decoder
   , lenientDecoder
   , strictDecoder
+
+  -- ** Helper types and functions
+  , Ignored
+  , Empty
+  , Tagged(..)
+  , untag
+
   , getField
   , getTag
   , parseJSON
   , parseUTCTime
   , parsePOSIXTime
 
-  -- *** Re-exports from tagged
-  , Tagged(..)
-  , untag
 
   -- * Database management
   , manage
@@ -110,6 +114,7 @@
 
 >>> :set -XOverloadedStrings
 >>> :set -XRecordWildCards
+>>> :set -XTypeApplications
 >>> import Database.InfluxDB
 >>> import qualified Database.InfluxDB.Format as F
 >>> import Control.Lens
@@ -146,7 +151,7 @@
 >>> let cpuUsage = "cpu_usage"
 >>> :{
 writeBatch wp
-  [ Line cpuUsage (Map.singleton "cpu" "cpu-total")
+  [ Line @UTCTime cpuUsage (Map.singleton "cpu" "cpu-total")
     (Map.fromList
       [ ("idle",   FieldFloat 10.1)
       , ("system", FieldFloat 53.3)
@@ -154,7 +159,7 @@
       ])
     (Just $ parseTimeOrError False defaultTimeLocale
       "%F %T%Q %Z"
-      "2017-06-17 15:41:40.42659044 UTC") :: Line UTCTime
+      "2017-06-17 15:41:40.42659044 UTC")
   ]
 :}
 
@@ -168,9 +173,9 @@
 If all the field types are an instance of 'Data.Aeson.FromJSON', we can use a
 tuple to store the results.
 
->>> :set -XDataKinds -XOverloadedStrings
+>>> :set -XDataKinds -XOverloadedStrings -XTypeOperators
 >>> type CPUUsage = (Tagged "time" UTCTime, Tagged "idle" Double, Tagged "system" Double, Tagged "user" Double)
->>> v <- query p $ formatQuery ("SELECT * FROM "%F.measurement) cpuUsage :: IO (V.Vector CPUUsage)
+>>> v <- query @CPUUsage p $ formatQuery ("SELECT * FROM "%F.measurement) cpuUsage
 >>> v
 [(Tagged 2017-06-17 15:41:40 UTC,Tagged 10.1,Tagged 53.3,Tagged 46.6)]
 
@@ -206,7 +211,7 @@
     return CPUUsage {..}
 :}
 
->>> query p $ formatQuery ("SELECT * FROM "%F.measurement) cpuUsage :: IO (V.Vector CPUUsage)
+>>> query @CPUUsage p $ formatQuery ("SELECT * FROM "%F.measurement) cpuUsage
 [CPUUsage {time = 2017-06-17 15:41:40 UTC, cpuIdle = 10.1, cpuSystem = 53.3, cpuUser = 46.6}]
 -}
 
diff --git a/src/Database/InfluxDB/Manage.hs b/src/Database/InfluxDB/Manage.hs
--- a/src/Database/InfluxDB/Manage.hs
+++ b/src/Database/InfluxDB/Manage.hs
@@ -43,7 +43,6 @@
 import Data.Scientific (toBoundedInteger)
 import Data.Text (Text)
 import Data.Time.Clock
-import Data.Void
 import qualified Data.Aeson.Types as A
 import qualified Data.Attoparsec.Combinator as AC
 import qualified Data.Attoparsec.Text as AT
@@ -76,9 +75,11 @@
     Left message ->
       throwIO $ UnexpectedResponse message request body
     Right val -> do
-      let parser = parseQueryResultsWith (params^.decoder) (params^.precision)
+      let parser = parseQueryResultsWith
+            (params ^. decoder)
+            (params ^. precision)
       case A.parse parser val of
-        A.Success (_ :: V.Vector Void) -> return ()
+        A.Success (_ :: V.Vector Empty) -> return ()
         A.Error message -> do
           let status = HC.responseStatus response
           when (HT.statusIsServerError status) $
@@ -107,7 +108,7 @@
     Server {..} = params^.server
 
 -- |
--- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
+-- >>> v <- query @ShowQuery (queryParams "_internal") "SHOW QUERIES"
 data ShowQuery = ShowQuery
   { showQueryQid :: !Int
   , showQueryText :: !Query
@@ -163,20 +164,20 @@
 
 -- | Query ID
 --
--- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
+-- >>> v <- query @ShowQuery (queryParams "_internal") "SHOW QUERIES"
 -- >>> v ^.. each.qid
 -- ...
 qid :: Lens' ShowQuery Int
 
 -- | Query text
 --
--- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
+-- >>> v <- query @ShowQuery (queryParams "_internal") "SHOW QUERIES"
 -- >>> v ^.. each.queryText
 -- ...
 queryText :: Lens' ShowQuery Query
 
 -- |
--- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
+-- >>> v <- query @ShowQuery (queryParams "_internal") "SHOW QUERIES"
 -- >>> v ^.. each.database
 -- ...
 instance HasDatabase ShowQuery where
@@ -184,7 +185,7 @@
 
 -- | Duration of the query
 --
--- >>> v <- query (queryParams "_internal") "SHOW QUERIES" :: IO (V.Vector ShowQuery)
+-- >>> v <- query @ShowQuery (queryParams "_internal") "SHOW QUERIES"
 -- >>> v ^.. each.duration
 -- ...
 duration :: Lens' ShowQuery NominalDiffTime
@@ -193,7 +194,7 @@
 
 -- | Series name
 --
--- >>> v <- query (queryParams "_internal") "SHOW SERIES" :: IO (V.Vector ShowSeries)
+-- >>> v <- query @ShowSeries (queryParams "_internal") "SHOW SERIES"
 -- >>> length $ v ^.. each.key
 -- ...
 key :: Lens' ShowSeries Key
diff --git a/src/Database/InfluxDB/Query.hs b/src/Database/InfluxDB/Query.hs
--- a/src/Database/InfluxDB/Query.hs
+++ b/src/Database/InfluxDB/Query.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE EmptyDataDeriving #-}
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE FlexibleInstances #-}
@@ -36,7 +37,9 @@
   -- * Low-level functions
   , withQueryResponse
 
-  -- * Re-exports from tagged
+  -- * Helper types
+  , Ignored
+  , Empty
   , Tagged(..)
   , untag
   ) where
@@ -44,6 +47,7 @@
 import Control.Monad
 import Data.Char
 import Data.List
+import Data.Maybe (fromMaybe)
 import Data.Proxy
 import GHC.TypeLits
 
@@ -62,8 +66,9 @@
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Builder as BB
 import qualified Data.ByteString.Lazy as BL
-import qualified Data.Text.Encoding as TE
 import qualified Data.Text as T
+import qualified Data.Text.Encoding as TE
+import qualified Data.Vector as V
 import qualified Network.HTTP.Client as HC
 import qualified Network.HTTP.Types as HT
 
@@ -72,8 +77,10 @@
 import qualified Database.InfluxDB.Format as F
 
 -- $setup
+-- >>> :set -XDataKinds
 -- >>> :set -XOverloadedStrings
 -- >>> :set -XRecordWildCards
+-- >>> :set -XTypeApplications
 -- >>> import Data.Time (UTCTime)
 -- >>> import qualified Data.Vector as V
 
@@ -99,14 +106,7 @@
 --     return H2OFeet {..}
 -- :}
 class QueryResults a where
-  -- | Parse a JSON object as an array of values of expected type.
-  parseResults
-    :: Precision 'QueryRequest
-    -> Value
-    -> A.Parser (Vector a)
-  parseResults = parseQueryResultsWith strictDecoder
-
-  -- | Parse a measurement in a JSON object.
+  -- | Parse a single measurement in a JSON object.
   parseMeasurement
     :: Precision 'QueryRequest
     -- ^ Timestamp precision
@@ -120,38 +120,88 @@
     -- ^ Field values
     -> A.Parser a
 
-{-# DEPRECATED parseResults
-  "Use 'parseQueryResults' or 'parseQueryResultsWith' " #-}
+  -- | Always use this 'Decoder' when decoding this type.
+  --
+  -- @'Just' dec@ means 'decoder' in 'QueryParams' will be ignored and be
+  -- replaced with the @dec@. 'Nothing' means 'decoder' in 'QueryParams' will
+  -- be used.
+  coerceDecoder :: proxy a -> Maybe Decoder
+  coerceDecoder _ = Nothing
 
 -- | Parse a JSON object as an array of values of expected type.
 parseQueryResults
-  :: QueryResults a
+  :: forall a. QueryResults a
   => Precision 'QueryRequest
   -> Value
   -> A.Parser (Vector a)
-parseQueryResults = parseQueryResultsWith strictDecoder
+parseQueryResults =
+  parseQueryResultsWith $
+    fromMaybe strictDecoder (coerceDecoder (Proxy :: Proxy a))
 
 parseQueryResultsWith
-  :: QueryResults a
+  :: forall a. QueryResults a
   => Decoder
   -> Precision 'QueryRequest
   -> Value
   -> A.Parser (Vector a)
 parseQueryResultsWith decoder prec =
-  parseResultsWithDecoder decoder (parseMeasurement prec)
+  parseResultsWithDecoder
+    (fromMaybe decoder (coerceDecoder (Proxy :: Proxy a)))
+    (parseMeasurement prec)
 
 -- | 'QueryResults' instance for empty results. Used by
 -- 'Database.InfluxDB.Manage.manage'.
+--
+-- NOTE: This instance is deprecated because it's unclear from the name whether
+-- it can be used to ignore results. Use 'Empty' when expecting an empty result.
+-- Use 'Ignored' if you want to ignore any results.
 instance QueryResults Void where
-  parseMeasurement _ _ _ _ _ = parseJSON A.emptyArray
+  parseMeasurement _ _ _ _ _ = fail "parseMeasurement for Void"
+  coerceDecoder _ = Just $ Decoder $ SomeDecoder
+    { decodeEach = id
+    , decodeFold = const $ pure V.empty
+    }
 
+-- | 'Ignored' can be used in the result type of 'query' when the result values
+-- are not needed.
+--
+-- >>> v <- query @Ignored (queryParams "dummy") "SHOW DATABASES"
+-- >>> v
+-- []
+data Ignored deriving Show
+
+-- | 'QueryResults' instance for ignoring results.
+instance QueryResults Ignored where
+  parseMeasurement _ _ _ _ _ = fail "parseMeasurement for Ignored"
+  coerceDecoder _ = Just $ Decoder $ SomeDecoder
+    { decodeEach = id -- doesn't matter
+    , decodeFold = const $ pure V.empty -- always succeeds with an empty vector
+    }
+
+-- | 'Empty' can be used in the result type of 'query' when the expected results
+-- are always empty. Note that if the results are not empty, the decoding
+-- process will fail:
+--
+-- >>> let p = queryParams "empty"
+-- >>> Database.InfluxDB.Manage.manage p "CREATE DATABASE empty"
+-- >>> v <- query @Empty p "SELECT * FROM empty" -- query an empty series
+-- >>> v
+-- []
+data Empty deriving Show
+
+-- | 'QueryResults' instance for empty results. Used by
+-- 'Database.InfluxDB.Manage.manage'.
+instance QueryResults Empty where
+  parseMeasurement _ _ _ _ _ = fail "parseMeasurement for Empty"
+  coerceDecoder _ = Just strictDecoder -- fail when the results are not empty
+
 fieldName :: KnownSymbol k => proxy k -> T.Text
 fieldName = T.pack . symbolVal
 
 -- | One-off type for non-timestamped measurements
 --
 -- >>> let p = queryParams "_internal"
--- >>> dbs <- query p "SHOW DATABASES" :: IO (V.Vector (Tagged "name" T.Text))
+-- >>> dbs <- query @(Tagged "name" T.Text) p "SHOW DATABASES"
 -- >>> find ((== "_internal") . untag) dbs
 -- Just (Tagged "_internal")
 instance (KnownSymbol k, FromJSON v) => QueryResults (Tagged k v) where
@@ -368,7 +418,7 @@
 --
 -- If you need a lower-level interface (e.g. to bypass the 'QueryResults'
 -- constraint etc), see 'withQueryResponse'.
-query :: QueryResults a => QueryParams -> Query -> IO (Vector a)
+query :: forall a. QueryResults a => QueryParams -> Query -> IO (Vector a)
 query params q = withQueryResponse params Nothing q go
   where
     go request response = do
@@ -378,7 +428,9 @@
         Left message -> throwIO $ UnexpectedResponse message request body
         Right val -> do
           let parser = parseQueryResultsWith
-                (queryDecoder params)
+                (fromMaybe
+                  (queryDecoder params)
+                  (coerceDecoder (Proxy :: Proxy a)))
                 (queryPrecision params)
           case A.parse parser val of
             A.Success vec -> return vec
@@ -441,7 +493,7 @@
               chunk' <- HC.responseBody response
               loop x k' chunk'
             AB.Done leftover val ->
-              case A.parse (parseResults (queryPrecision params)) val of
+              case A.parse (parseQueryResults (queryPrecision params)) val of
                 A.Success vec -> do
                   x' <- step x vec
                   loop x' k0 leftover
diff --git a/src/Database/InfluxDB/Write.hs b/src/Database/InfluxDB/Write.hs
--- a/src/Database/InfluxDB/Write.hs
+++ b/src/Database/InfluxDB/Write.hs
@@ -46,7 +46,7 @@
 import Database.InfluxDB.JSON
 
 -- $setup
--- >>> :set -XOverloadedStrings -XNoOverloadedLists
+-- >>> :set -XOverloadedStrings -XNoOverloadedLists -XTypeApplications
 -- >>> import qualified Data.Map as Map
 -- >>> import Data.Time
 -- >>> import Database.InfluxDB
@@ -109,7 +109,7 @@
 -- | Write a 'Line'.
 --
 -- >>> let p = writeParams "test-db"
--- >>> write p $ Line "room_temp" Map.empty (Map.fromList [("temp", FieldFloat 25.0)]) (Nothing :: Maybe UTCTime)
+-- >>> write p $ Line @UTCTime "room_temp" Map.empty (Map.fromList [("temp", FieldFloat 25.0)]) Nothing
 write
   :: Timestamp time
   => WriteParams
@@ -125,8 +125,8 @@
 -- >>> let p = writeParams "test-db"
 -- >>> :{
 -- writeBatch p
---   [ Line "temp" (Map.singleton "city" "tokyo") (Map.fromList [("temp", FieldFloat 25.0)]) (Nothing :: Maybe UTCTime)
---   , Line "temp" (Map.singleton "city" "osaka") (Map.fromList [("temp", FieldFloat 25.2)]) (Nothing :: Maybe UTCTime)
+--   [ Line @UTCTime "temp" (Map.singleton "city" "tokyo") (Map.fromList [("temp", FieldFloat 25.0)]) Nothing
+--   , Line @UTCTime "temp" (Map.singleton "city" "osaka") (Map.fromList [("temp", FieldFloat 25.2)]) Nothing
 --   ]
 -- :}
 writeBatch
diff --git a/tests/regressions.hs b/tests/regressions.hs
--- a/tests/regressions.hs
+++ b/tests/regressions.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE QuasiQuotes #-}
@@ -23,14 +24,15 @@
   [ testCase "issue #64" case_issue64
   , testCase "issue #66" case_issue66
   , testCaseSteps "issue #75" case_issue75
+  , testCaseSteps "issue #79" case_issue79
   ]
 
 -- https://github.com/maoe/influxdb-haskell/issues/64
 case_issue64 :: Assertion
 case_issue64 = withDatabase dbName $ do
-  write wp $ Line "count" Map.empty
+  write wp $ Line @UTCTime "count" Map.empty
     (Map.fromList [("value", FieldInt 1)])
-    (Nothing :: Maybe UTCTime)
+    Nothing
   r <- try $ query qp "SELECT value FROM count"
   case r of
     Left err -> case err of
@@ -70,9 +72,9 @@
   step "Checking encoded value"
   let string = [Raw.r|bl\"a|]
   let encoded = encodeLine (scaleTo Nanosecond)
-        $ Line "testing" mempty
+        $ Line @UTCTime "testing" mempty
           (M.singleton "test" $ FieldString string)
-          (Nothing :: Maybe UTCTime)
+          Nothing
   encoded @?= [Raw.r|testing test="bl\\\"a"|]
 
   step "Preparing a test database"
@@ -84,6 +86,26 @@
   step "Checking server response"
   let wp = writeParams db
   writeByteString wp encoded
+
+case_issue79 :: (String -> IO ()) -> Assertion
+case_issue79 step = withDatabase db $ do
+  let w = writeParams db
+  let q = queryParams db
+  step "Querying an empty series with two fields expected"
+  _ <- query @(Tagged "time" UTCTime, Tagged "value" Int) q "SELECT * FROM foo"
+  step "Querying an empty series with the results ignored"
+  _ <- query @Ignored q "SELECT * FROM foo"
+  step "Querying an empty series expecting an empty result"
+  _ <- query @Empty q "SELECT * FROM foo"
+  step "Writing a data point"
+  write w $ Line @UTCTime "foo" mempty (Map.fromList [("value", FieldInt 42)]) Nothing
+  step "Querying a non-empty series with two fields expected"
+  _ <- query @(Tagged "time" UTCTime, Tagged "value" Int) q "SELECT * FROM foo"
+  step "Querying a non-empty series with the results ignored"
+  _ <- query @Ignored q "SELECT * FROM foo"
+  return ()
+  where
+    db = "case_issue79"
 
 withDatabase :: Database -> IO a -> IO a
 withDatabase dbName f = bracket_
