diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,17 @@
 Brick changelog
 ---------------
 
+0.36.1
+------
+
+Package changes:
+ * Raiseed upper bound to support GHC 8.4.2 (#171)
+
+Other changes:
+ * Improved List accessor documentation (thanks liam <liam@magicseaweed.com>)
+ * Brick.Main now uses a Set instead a list to track invalidation
+   requests to avoid duplicates.
+
 0.36
 ----
 
diff --git a/brick.cabal b/brick.cabal
--- a/brick.cabal
+++ b/brick.cabal
@@ -1,5 +1,5 @@
 name:                brick
-version:             0.36
+version:             0.36.1
 synopsis:            A declarative terminal user interface library
 description:
   Write terminal applications painlessly with 'brick'! You write an
@@ -86,7 +86,7 @@
     Brick.Types.Internal
     Brick.Widgets.Internal
 
-  build-depends:       base <= 4.11.0.0,
+  build-depends:       base <= 4.11.1.0,
                        vty >= 5.18.1,
                        transformers,
                        data-clist >= 0.1,
diff --git a/src/Brick/Main.hs b/src/Brick/Main.hs
--- a/src/Brick/Main.hs
+++ b/src/Brick/Main.hs
@@ -52,6 +52,7 @@
 import Control.Applicative ((<$>))
 import Data.Monoid (mempty)
 #endif
+import qualified Data.Foldable as F
 import Data.Maybe (listToMaybe)
 import qualified Data.Map as M
 import qualified Data.Set as S
@@ -219,7 +220,7 @@
                     newVty <- buildVty
                     run newVty newRS newAppState brickChan
 
-        emptyES = ES [] []
+        emptyES = ES [] mempty
         eventRO = EventRO M.empty initialVty mempty
     (st, eState) <- runStateT (runReaderT (runEventM (appStartEvent app initialAppState)) eventRO) emptyES
     let initialRS = RS M.empty (esScrollRequests eState) S.empty mempty []
@@ -293,7 +294,7 @@
                 _ -> return (e, firstRS, exts)
         _ -> return (e, firstRS, exts)
 
-    let emptyES = ES [] []
+    let emptyES = ES [] mempty
         eventRO = EventRO (viewportMap nextRS) vty nextExts
 
     (next, eState) <- runStateT (runReaderT (runEventM (appHandleEvent app appState e'))
@@ -303,11 +304,14 @@
                                          renderCache nextRS
                          })
 
-applyInvalidations :: (Ord n) => [CacheInvalidateRequest n] -> M.Map n v -> M.Map n v
-applyInvalidations ns cache = foldr (.) id (mkFunc <$> ns) cache
+applyInvalidations :: (Ord n) => S.Set (CacheInvalidateRequest n) -> M.Map n v -> M.Map n v
+applyInvalidations ns cache =
+    if InvalidateEntire `S.member` ns
+    then mempty
+    else foldr (.) id (mkFunc <$> F.toList ns) cache
     where
-    mkFunc InvalidateEntire = const mempty
-    mkFunc (InvalidateSingle n) = M.delete n
+        mkFunc InvalidateEntire = const mempty
+        mkFunc (InvalidateSingle n) = M.delete n
 
 -- | Given a viewport name, get the viewport's size and offset
 -- information from the most recent rendering. Returns 'Nothing' if
@@ -348,14 +352,14 @@
 
 -- | Invalidate the rendering cache entry with the specified resource
 -- name.
-invalidateCacheEntry :: n -> EventM n ()
+invalidateCacheEntry :: (Ord n) => n -> EventM n ()
 invalidateCacheEntry n = EventM $ do
-    lift $ modify (\s -> s { cacheInvalidateRequests = InvalidateSingle n : cacheInvalidateRequests s })
+    lift $ modify (\s -> s { cacheInvalidateRequests = S.insert (InvalidateSingle n) $ cacheInvalidateRequests s })
 
 -- | Invalidate the entire rendering cache.
-invalidateCache :: EventM n ()
+invalidateCache :: (Ord n) => EventM n ()
 invalidateCache = EventM $ do
-    lift $ modify (\s -> s { cacheInvalidateRequests = InvalidateEntire : cacheInvalidateRequests s })
+    lift $ modify (\s -> s { cacheInvalidateRequests = S.insert InvalidateEntire $ cacheInvalidateRequests s })
 
 withVty :: Vty -> (Vty -> IO a) -> IO a
 withVty vty useVty = do
diff --git a/src/Brick/Types/Internal.hs b/src/Brick/Types/Internal.hs
--- a/src/Brick/Types/Internal.hs
+++ b/src/Brick/Types/Internal.hs
@@ -105,11 +105,13 @@
                   -- ^ Viewports of this type are scrollable vertically and horizontally.
                   deriving (Show, Eq)
 
-data CacheInvalidateRequest n = InvalidateSingle n
-                              | InvalidateEntire
+data CacheInvalidateRequest n =
+    InvalidateSingle n
+    | InvalidateEntire
+    deriving (Ord, Eq)
 
 data EventState n = ES { esScrollRequests :: [(n, ScrollRequest)]
-                       , cacheInvalidateRequests :: [CacheInvalidateRequest n]
+                       , cacheInvalidateRequests :: S.Set (CacheInvalidateRequest n)
                        }
 
 -- | An extent of a named area: its size, location, and origin.
diff --git a/src/Brick/Widgets/List.hs b/src/Brick/Widgets/List.hs
--- a/src/Brick/Widgets/List.hs
+++ b/src/Brick/Widgets/List.hs
@@ -9,7 +9,7 @@
 -- | This module provides a scrollable list type and functions for
 -- manipulating and rendering it.
 module Brick.Widgets.List
-  ( List(listElements, listSelected, listName, listItemHeight)
+  ( List
 
   -- * Constructing a list
   , list
@@ -27,6 +27,13 @@
   , listNameL
   , listItemHeightL
 
+  -- * Accessors
+  , listElements
+  , listName
+  , listSelectedElement
+  , listSelected
+  , listItemHeight
+
   -- * Manipulating a list
   , listMoveBy
   , listMoveTo
@@ -38,7 +45,6 @@
   , listInsert
   , listRemove
   , listReplace
-  , listSelectedElement
   , listClear
   , listReverse
   , listModify
@@ -78,9 +84,13 @@
 --   list
 data List n e =
     List { listElements :: !(V.Vector e)
+         -- ^ The list's vector of elements.
          , listSelected :: !(Maybe Int)
+         -- ^ The list's selected element index, if any.
          , listName :: n
+         -- ^ The list's name.
          , listItemHeight :: Int
+         -- ^ The height of the list items.
          } deriving (Functor, Foldable, Traversable, Show)
 
 suffixLenses ''List
