diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,16 @@
 Brick changelog
 ---------------
 
+0.47.1
+------
+
+Bug fixes:
+ * userguide: update stale Result construction
+ * Added test case for List initial selection (thanks Fraser Tweedale)
+ * Fixed build on GHC 7.10 due to RULES pragma formatting issue (thanks
+   Fraser Tweedale)
+ * Various CI-related fixes (thanks Fraser Tweedale)
+
 0.47
 ----
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -44,7 +44,7 @@
 at these projects:
 
  * `tetris`, an implementation of the Tetris game: https://github.com/SamTay/tetris
- * `gotta-go-fast`, a typing tutor: https://github.com/hot-leaf-juice/gotta-go-fast
+ * `gotta-go-fast`, a typing tutor: https://github.com/callum-oakley/gotta-go-fast
  * `haskell-player`, an `afplay` frontend: https://github.com/potomak/haskell-player
  * `mushu`, an `MPD` client: https://github.com/elaye/mushu
  * `matterhorn`, a client for [Mattermost](https://about.mattermost.com/): https://github.com/matterhorn-chat/matterhorn
@@ -60,6 +60,7 @@
  * `VOIDSPACE`, a space-themed typing-tutor game: https://github.com/ChrisPenner/void-space
  * `solitaire`, the card game: https://github.com/ambuc/solitaire
  * `sudoku-tui`, a Sudoku implementation: https://github.com/evanrelf/sudoku-tui
+ * `summoner-tui`, an interactive frontend to the Summoner tool: https://github.com/kowainik/summoner/tree/master/summoner-tui
 
 These third-party packages also extend `brick`:
 
diff --git a/brick.cabal b/brick.cabal
--- a/brick.cabal
+++ b/brick.cabal
@@ -1,5 +1,5 @@
 name:                brick
-version:             0.47
+version:             0.47.1
 synopsis:            A declarative terminal user interface library
 description:
   Write terminal applications painlessly with 'brick'! You write an
@@ -37,7 +37,7 @@
 cabal-version:       1.18
 Homepage:            https://github.com/jtdaugherty/brick/
 Bug-reports:         https://github.com/jtdaugherty/brick/issues
-tested-with:         GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.1
+tested-with:         GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.1, GHC == 8.6.5
 
 extra-doc-files:     README.md,
                      docs/guide.rst,
diff --git a/docs/guide.rst b/docs/guide.rst
--- a/docs/guide.rst
+++ b/docs/guide.rst
@@ -1804,7 +1804,7 @@
            ctx <- getContext
            let a = ctx^.attrL
            return $ Result (Graphics.Vty.charFill a ch (ctx^.availWidthL) (ctx^.availHeightL))
-                           [] []
+                           [] [] [] Brick.BorderMap.empty
 
 Rendering Sub-Widgets
 ---------------------
diff --git a/docs/samtay-tutorial.md b/docs/samtay-tutorial.md
--- a/docs/samtay-tutorial.md
+++ b/docs/samtay-tutorial.md
@@ -386,8 +386,8 @@
 
 The score is straightforward, but it is the first border in
 this tutorial. Borders are well documented in the [border
-demo](https://github.com/jtdaugherty/brick/blob/master/programs/BorderDe
-mo.hs) and the Haddocks for that matter.
+demo](https://github.com/jtdaugherty/brick/blob/master/programs/BorderDemo.hs)
+and the Haddocks for that matter.
 
 We also only show the "game over" widget if the game is actually over.
 In that case, we are rendering the string widget with the `gameOverAttr`
diff --git a/src/Brick/Widgets/Core.hs b/src/Brick/Widgets/Core.hs
--- a/src/Brick/Widgets/Core.hs
+++ b/src/Brick/Widgets/Core.hs
@@ -1261,4 +1261,4 @@
 "vBox2"    forall as bs . vBox [vBox as, vBox bs] = vBox (as ++ bs)
 "vboxL"    forall as b  . vBox [vBox as, b]       = vBox (as ++ [b])
 "vboxR"    forall a bs  . vBox [a, vBox bs]       = vBox (a : bs)
-#-}
+  #-}
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
@@ -418,7 +418,7 @@
            -- size)
            -> GenericList n t e
            -> GenericList n t e
-listRemove pos l | null (l^.listElementsL) = l
+listRemove pos l | null l = l
                  | pos /= splitClamp l pos = l
                  | otherwise =
     let newSel = case l^.listSelectedL of
@@ -517,7 +517,7 @@
     let target = case l ^. listSelectedL of
             Nothing
                 | amt > 0 -> 0
-                | otherwise -> length (l ^. listElementsL) - 1
+                | otherwise -> length l - 1
             Just i -> max 0 (amt + i)  -- don't be negative
     in listMoveTo target l
 
@@ -541,12 +541,10 @@
            -> GenericList n t e
            -> GenericList n t e
 listMoveTo pos l =
-    let len = length (l ^. listElementsL)
+    let len = length l
         i = if pos < 0 then len - pos else pos
         newSel = splitClamp l i
-    in l & listSelectedL .~ if not (null (l ^. listElementsL))
-                            then Just newSel
-                            else Nothing
+    in l & listSelectedL .~ if null l then Nothing else Just newSel
 
 -- | Split-based clamp that avoids evaluating 'length' of the structure
 -- (unless the structure is already fully evaluated).
@@ -560,7 +558,7 @@
         --
         -- Otherwise if tail is not empty, then we already know that i
         -- is in the list, so we don't need to know the length
-        clamp 0 (if null t then length (l ^. listElementsL) - 1 else i) i
+        clamp 0 (if null t then length l - 1 else i) i
 
 -- | Set the selected index for a list to the index of the first
 -- occurence of the specified element if it is in the list, or leave
@@ -627,7 +625,7 @@
             -> GenericList n t e
 listReverse l =
     l & listElementsL %~ reverse
-      & listSelectedL %~ fmap (length (l ^. listElementsL) - 1 -)
+      & listSelectedL %~ fmap (length l - 1 -)
 
 -- | Apply a function to the selected element. If no element is selected
 -- the list is not modified.
diff --git a/tests/List.hs b/tests/List.hs
--- a/tests/List.hs
+++ b/tests/List.hs
@@ -98,6 +98,13 @@
   => (op a -> List n a -> List n a) -> t (op a) -> List n a -> List n a
 applyListOps f = appEndo . foldMap (Endo . f)
 
+
+-- | Initial selection is always 0 (or Nothing for empty list)
+prop_initialSelection :: [a] -> Bool
+prop_initialSelection xs =
+  list () (V.fromList xs) 1 ^. listSelectedL ==
+    if null xs then Nothing else Just 0
+
 -- list operations keep the selected index in bounds
 prop_listOpsMaintainSelectedValid
   :: (Eq a) => [ListOp a] -> List n a -> Bool
@@ -106,9 +113,9 @@
   in
     case l' ^. listSelectedL of
       -- either there is no selection and list is empty
-      Nothing -> null (l' ^. listElementsL)
+      Nothing -> null l'
       -- or the selected index is valid
-      Just i -> i >= 0 && i < length (l' ^. listElementsL)
+      Just i -> i >= 0 && i < length l'
 
 -- reversing a list keeps the selected element the same
 prop_reverseMaintainsSelectedElement
@@ -124,7 +131,7 @@
 -- reversing maintains size of list
 prop_reverseMaintainsSizeOfList :: List n a -> Bool
 prop_reverseMaintainsSizeOfList l =
-  length (l ^. listElementsL) == length (listReverse l ^. listElementsL)
+  length l == length (listReverse l)
 
 -- an inserted element may always be found at the given index
 -- (when target index is clamped to 0 <= n <= len)
@@ -132,7 +139,7 @@
 prop_insert i a l =
   let
     l' = listInsert i a l
-    i' = clamp 0 (length (l ^. listElementsL)) i
+    i' = clamp 0 (length l) i
   in
     listSelectedElement (listMoveTo i' l') == Just (i', a)
 
@@ -142,7 +149,7 @@
   let
     l' = listInsert i a l
   in
-    length (l' ^. listElementsL) == length (l ^. listElementsL) + 1
+    length l' == length l + 1
 
 -- inserting an element and moving to it always succeeds and
 -- the selected element is the one we inserted.
@@ -169,7 +176,7 @@
     l' = applyListOps op ops l
     l'' = set listSelectedL Nothing . listInsert i a $ l'
     seeks = converging ((==) `on` (^. listSelectedL)) (listFindBy (== a)) l''
-    i' = clamp 0 (length (l' ^. listElementsL)) i -- we can't have inserted past len
+    i' = clamp 0 (length l') i -- we can't have inserted past len
   in
     (find ((== Just i') . (^. listSelectedL)) seeks >>= listSelectedElement)
     == Just (i', a)
@@ -188,7 +195,7 @@
 prop_insertRemove :: (Eq a) => Int -> a -> List n a -> Bool
 prop_insertRemove i a l =
   let
-    i' = clamp 0 (length (l ^. listElementsL)) i
+    i' = clamp 0 (length l) i
     l' = listInsert i' a l -- pre-clamped
     l'' = listRemove i' l'
   in
@@ -199,13 +206,13 @@
 prop_remove :: Int -> List n a -> Bool
 prop_remove i l =
   let
-    len = length (l ^. listElementsL)
+    len = length l
     i' = clamp 0 (len - 1) i
     test
       | len > 0 && i == i' = (== len - 1)  -- i is in bounds
       | otherwise = (== len)               -- i is out of bounds
   in
-    test (length (listRemove i l ^. listElementsL))
+    test (length (listRemove i l))
 
 -- deleting an element and re-inserting it at same position
 -- gives the original list elements
@@ -234,7 +241,7 @@
   let
     l' = applyListOps op ops l
     l'' = converge ((==) `on` (^. listSelectedL)) listMoveUp l'
-    len = length (l'' ^. listElementsL)
+    len = length l''
   in
     maybe (len == 0) (== 0) (l'' ^. listSelectedL)
 
@@ -244,7 +251,7 @@
   let
     l' = applyListOps op ops l
     l'' = converge ((==) `on` (^. listSelectedL)) listMoveDown l'
-    len = length (l'' ^. listElementsL)
+    len = length l''
   in
     maybe (len == 0) (== len - 1) (l'' ^. listSelectedL)
 
@@ -292,7 +299,7 @@
 prop_moveByWhenNoSelection l amt =
   let
     l' = l & listSelectedL .~ Nothing
-    len = length (l ^. listElementsL)
+    len = length l
     expected = if amt > 0 then 0 else len - 1
   in
     len > 0 ==> listMoveBy amt l' ^. listSelectedL == Just expected
