diff --git a/Data/Complex.hs b/Data/Complex.hs
--- a/Data/Complex.hs
+++ b/Data/Complex.hs
@@ -50,17 +50,41 @@
 -- -----------------------------------------------------------------------------
 -- The Complex type
 
--- | Complex numbers are an algebraic type.
+-- | A data type representing complex numbers.
 --
--- For a complex number @z@, @'abs' z@ is a number with the magnitude of @z@,
--- but oriented in the positive real direction, whereas @'signum' z@
--- has the phase of @z@, but unit magnitude.
+-- You can read about complex numbers [on wikipedia](https://en.wikipedia.org/wiki/Complex_number).
 --
--- The 'Foldable' and 'Traversable' instances traverse the real part first.
+-- In haskell, complex numbers are represented as @a :+ b@ which can be thought of
+-- as representing \(a + bi\). For a complex number @z@, @'abs' z@ is a number with the 'magnitude' of @z@,
+-- but oriented in the positive real direction, whereas @'signum' z@
+-- has the 'phase' of @z@, but unit 'magnitude'.
+-- Apart from the loss of precision due to IEEE754 floating point numbers,
+-- it holds that @z == 'abs' z * 'signum' z@.
 --
 -- Note that `Complex`'s instances inherit the deficiencies from the type
 -- parameter's. For example, @Complex Float@'s 'Ord' instance has similar
 -- problems to `Float`'s.
+--
+-- As can be seen in the examples, the 'Foldable'
+-- and 'Traversable' instances traverse the real part first.
+--
+-- ==== __Examples__
+--
+-- >>> (5.0 :+ 2.5) + 6.5
+-- 11.5 :+ 2.5
+--
+-- >>> abs (1.0 :+ 1.0) - sqrt 2.0
+-- 0.0 :+ 0.0
+--
+-- >>> abs (signum (4.0 :+ 3.0))
+-- 1.0 :+ 0.0
+--
+-- >>> foldr (:) [] (1 :+ 2)
+-- [1,2]
+--
+-- >>> mapM print (1 :+ 2)
+-- 1
+-- 2
 data Complex a
   = !a :+ !a    -- ^ forms a complex number from its real and imaginary
                 -- rectangular components.
@@ -79,38 +103,113 @@
 -- Functions over Complex
 
 -- | Extracts the real part of a complex number.
+--
+-- ==== __Examples__
+--
+-- >>> realPart (5.0 :+ 3.0)
+-- 5.0
+--
+-- >>> realPart ((5.0 :+ 3.0) * (2.0 :+ 3.0))
+-- 1.0
 realPart :: Complex a -> a
 realPart (x :+ _) =  x
 
 -- | Extracts the imaginary part of a complex number.
+--
+-- ==== __Examples__
+--
+-- >>> imagPart (5.0 :+ 3.0)
+-- 3.0
+--
+-- >>> imagPart ((5.0 :+ 3.0) * (2.0 :+ 3.0))
+-- 21.0
 imagPart :: Complex a -> a
 imagPart (_ :+ y) =  y
 
--- | The conjugate of a complex number.
+-- | The 'conjugate' of a complex number.
+--
+-- prop> conjugate (conjugate x) = x
+--
+-- ==== __Examples__
+--
+-- >>> conjugate (3.0 :+ 3.0)
+-- 3.0 :+ (-3.0)
+--
+-- >>> conjugate ((3.0 :+ 3.0) * (2.0 :+ 2.0))
+-- 0.0 :+ (-12.0)
 {-# SPECIALISE conjugate :: Complex Double -> Complex Double #-}
 conjugate        :: Num a => Complex a -> Complex a
 conjugate (x:+y) =  x :+ (-y)
 
--- | Form a complex number from polar components of magnitude and phase.
+-- | Form a complex number from 'polar' components of 'magnitude' and 'phase'.
+--
+-- ==== __Examples__
+--
+-- >>> mkPolar 1 (pi / 4)
+-- 0.7071067811865476 :+ 0.7071067811865475
+--
+-- >>> mkPolar 1 0
+-- 1.0 :+ 0.0
 {-# SPECIALISE mkPolar :: Double -> Double -> Complex Double #-}
 mkPolar          :: Floating a => a -> a -> Complex a
 mkPolar r theta  =  r * cos theta :+ r * sin theta
 
--- | @'cis' t@ is a complex value with magnitude @1@
--- and phase @t@ (modulo @2*'pi'@).
+-- | @'cis' t@ is a complex value with 'magnitude' @1@
+-- and 'phase' @t@ (modulo @2*'pi'@).
+--
+-- @
+-- 'cis' = 'mkPolar' 1
+-- @
+--
+-- ==== __Examples__
+--
+-- >>> cis 0
+-- 1.0 :+ 0.0
+--
+-- The following examples are not perfectly zero due to [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754)
+--
+-- >>> cis pi
+-- (-1.0) :+ 1.2246467991473532e-16
+--
+-- >>> cis (4 * pi) - cis (2 * pi)
+-- 0.0 :+ (-2.4492935982947064e-16)
 {-# SPECIALISE cis :: Double -> Complex Double #-}
 cis              :: Floating a => a -> Complex a
 cis theta        =  cos theta :+ sin theta
 
 -- | The function 'polar' takes a complex number and
--- returns a (magnitude, phase) pair in canonical form:
--- the magnitude is nonnegative, and the phase in the range @(-'pi', 'pi']@;
--- if the magnitude is zero, then so is the phase.
+-- returns a ('magnitude', 'phase') pair in canonical form:
+-- the 'magnitude' is non-negative, and the 'phase' in the range @(-'pi', 'pi']@;
+-- if the 'magnitude' is zero, then so is the 'phase'.
+--
+-- @'polar' z = ('magnitude' z, 'phase' z)@
+--
+-- ==== __Examples__
+--
+-- >>> polar (1.0 :+ 1.0)
+-- (1.4142135623730951,0.7853981633974483)
+--
+-- >>> polar ((-1.0) :+ 0.0)
+-- (1.0,3.141592653589793)
+--
+-- >>> polar (0.0 :+ 0.0)
+-- (0.0,0.0)
 {-# SPECIALISE polar :: Complex Double -> (Double,Double) #-}
 polar            :: (RealFloat a) => Complex a -> (a,a)
 polar z          =  (magnitude z, phase z)
 
--- | The nonnegative magnitude of a complex number.
+-- | The non-negative 'magnitude' of a complex number.
+--
+-- ==== __Examples__
+--
+-- >>> magnitude (1.0 :+ 1.0)
+-- 1.4142135623730951
+--
+-- >>> magnitude (1.0 + 0.0)
+-- 1.0
+--
+-- >>> magnitude (0.0 :+ (-5.0))
+-- 5.0
 {-# SPECIALISE magnitude :: Complex Double -> Double #-}
 magnitude :: (RealFloat a) => Complex a -> a
 magnitude (x:+y) =  scaleFloat k
@@ -119,8 +218,16 @@
                           mk = - k
                           sqr z = z * z
 
--- | The phase of a complex number, in the range @(-'pi', 'pi']@.
--- If the magnitude is zero, then so is the phase.
+-- | The 'phase' of a complex number, in the range @(-'pi', 'pi']@.
+-- If the 'magnitude' is zero, then so is the 'phase'.
+--
+-- ==== __Examples__
+--
+-- >>> phase (0.5 :+ 0.5) / pi
+-- 0.25
+--
+-- >>> phase (0 :+ 4) / pi
+-- 0.5
 {-# SPECIALISE phase :: Complex Double -> Double #-}
 phase :: (RealFloat a) => Complex a -> a
 phase (0 :+ 0)   = 0            -- SLPJ July 97 from John Peterson
diff --git a/Data/Data.hs b/Data/Data.hs
--- a/Data/Data.hs
+++ b/Data/Data.hs
@@ -631,6 +631,8 @@
                         }
 
 -- | Constructs a constructor
+--
+-- @since 4.16.0.0
 mkConstrTag :: DataType -> String -> Int -> [String] -> Fixity -> Constr
 mkConstrTag dt str idx fields fix =
         Constr
diff --git a/Data/Monoid.hs b/Data/Monoid.hs
--- a/Data/Monoid.hs
+++ b/Data/Monoid.hs
@@ -127,14 +127,18 @@
 -- @'First' a@ is isomorphic to @'Alt' 'Maybe' a@, but precedes it
 -- historically.
 --
--- >>> getFirst (First (Just "hello") <> First Nothing <> First (Just "world"))
--- Just "hello"
---
 -- Beware that @Data.Monoid.@'First' is different from
 -- @Data.Semigroup.@'Data.Semigroup.First'. The former returns the first non-'Nothing',
 -- so @Data.Monoid.First Nothing <> x = x@. The latter simply returns the first value,
 -- thus @Data.Semigroup.First Nothing <> x = Data.Semigroup.First Nothing@.
 --
+-- ==== __Examples__
+--
+-- >>> First (Just "hello") <> First Nothing <> First (Just "world")
+-- First {getFirst = Just "hello"}
+--
+-- >>> First Nothing <> mempty
+-- First {getFirst = Nothing}
 newtype First a = First { getFirst :: Maybe a }
         deriving ( Eq          -- ^ @since 2.01
                  , Ord         -- ^ @since 2.01
@@ -162,14 +166,17 @@
 -- @'Last' a@ is isomorphic to @'Dual' ('First' a)@, and thus to
 -- @'Dual' ('Alt' 'Maybe' a)@
 --
--- >>> getLast (Last (Just "hello") <> Last Nothing <> Last (Just "world"))
--- Just "world"
---
--- Beware that @Data.Monoid.@'Last' is different from
 -- @Data.Semigroup.@'Data.Semigroup.Last'. The former returns the last non-'Nothing',
 -- so @x <> Data.Monoid.Last Nothing = x@. The latter simply returns the last value,
 -- thus @x <> Data.Semigroup.Last Nothing = Data.Semigroup.Last Nothing@.
 --
+-- ==== __Examples__
+--
+-- >>> Last (Just "hello") <> Last Nothing <> Last (Just "world")
+-- Last {getLast = Just "world"}
+--
+-- >>> Last Nothing <> mempty
+-- Last {getLast = Nothing}
 newtype Last a = Last { getLast :: Maybe a }
         deriving ( Eq          -- ^ @since 2.01
                  , Ord         -- ^ @since 2.01
@@ -194,6 +201,14 @@
 
 -- | This data type witnesses the lifting of a 'Monoid' into an
 -- 'Applicative' pointwise.
+--
+-- ==== __Examples__
+--
+-- >>> Ap (Just [1, 2, 3]) <> Ap Nothing
+-- Ap {getAp = Nothing}
+--
+-- >>> Ap [Sum 10, Sum 20] <> Ap [Sum 1, Sum 2]
+-- Ap {getAp = [Sum {getSum = 11},Sum {getSum = 12},Sum {getSum = 21},Sum {getSum = 22}]}
 --
 -- @since 4.12.0.0
 newtype Ap f a = Ap { getAp :: f a }
diff --git a/Data/Semigroup.hs b/Data/Semigroup.hs
--- a/Data/Semigroup.hs
+++ b/Data/Semigroup.hs
@@ -26,6 +26,7 @@
 --
 -- The 'Min' 'Semigroup' instance for 'Int' is defined to always pick the smaller
 -- number:
+--
 -- >>> Min 1 <> Min 2 <> Min 3 <> Min 4 :: Min Int
 -- Min {getMin = 1}
 --
@@ -48,6 +49,7 @@
 --
 -- >>> sconcat (1 :| [2, 3, 4]) :: Min Int
 -- Min {getMin = 1}
+--
 -- >>> sconcat (1 :| [2, 3, 4]) :: Max Int
 -- Max {getMax = 4}
 --
@@ -120,28 +122,56 @@
 
 -- | A generalization of 'Data.List.cycle' to an arbitrary 'Semigroup'.
 -- May fail to terminate for some values in some semigroups.
+--
+-- ==== __Examples__
+--
+-- >>> take 10 $ cycle1 [1, 2, 3]
+-- [1,2,3,1,2,3,1,2,3,1]
+--
+-- >>> cycle1 (Right 1)
+-- Right 1
+--
+-- >>> cycle1 (Left 1)
+-- * hangs forever *
 cycle1 :: Semigroup m => m -> m
 cycle1 xs = xs' where xs' = xs <> xs'
 
 -- | This lets you use a difference list of a 'Semigroup' as a 'Monoid'.
 --
--- === __Example:__
--- >>> let hello = diff "Hello, "
+-- ==== __Examples__
+--
+-- > let hello = diff "Hello, "
+--
 -- >>> appEndo hello "World!"
 -- "Hello, World!"
+--
 -- >>> appEndo (hello <> mempty) "World!"
 -- "Hello, World!"
+--
 -- >>> appEndo (mempty <> hello) "World!"
 -- "Hello, World!"
--- >>> let world = diff "World"
--- >>> let excl = diff "!"
+--
+-- > let world = diff "World"
+-- > let excl = diff "!"
+--
 -- >>> appEndo (hello <> (world <> excl)) mempty
 -- "Hello, World!"
+--
 -- >>> appEndo ((hello <> world) <> excl) mempty
 -- "Hello, World!"
 diff :: Semigroup m => m -> Endo m
 diff = Endo . (<>)
 
+-- | The 'Min' 'Monoid' and 'Semigroup' always choose the smaller element as
+-- by the 'Ord' instance and 'min' of the contained type.
+--
+-- ==== __Examples__
+--
+-- >>> Min 42 <> Min 3
+-- Min 3
+--
+-- >>> sconcat $ Min 1 :| [ Min n | n <- [2 .. 100]]
+-- Min {getMin = 1}
 newtype Min a = Min { getMin :: a }
   deriving ( Bounded  -- ^ @since 4.9.0.0
            , Eq       -- ^ @since 4.9.0.0
@@ -217,6 +247,16 @@
   signum (Min a) = Min (signum a)
   fromInteger    = Min . fromInteger
 
+-- | The 'Max' 'Monoid' and 'Semigroup' always choose the bigger element as
+-- by the 'Ord' instance and 'max' of the contained type.
+--
+-- ==== __Examples__
+--
+-- >>> Max 42 <> Max 3
+-- Max 42
+--
+-- >>> sconcat $ Max 1 :| [ Max n | n <- [2 .. 100]]
+-- Max {getMax = 100}
 newtype Max a = Max { getMax :: a }
   deriving ( Bounded  -- ^ @since 4.9.0.0
            , Eq       -- ^ @since 4.9.0.0
@@ -294,8 +334,16 @@
 -- | 'Arg' isn't itself a 'Semigroup' in its own right, but it can be
 -- placed inside 'Min' and 'Max' to compute an arg min or arg max.
 --
+-- ==== __Examples__
+--
 -- >>> minimum [ Arg (x * x) x | x <- [-10 .. 10] ]
 -- Arg 0 0
+--
+-- >>> maximum [ Arg (-0.2*x^2 + 1.5*x + 1) x | x <- [-10 .. 10] ]
+-- Arg 3.8 4.0
+--
+-- >>> minimum [ Arg (-0.2*x^2 + 1.5*x + 1) x | x <- [-10 .. 10] ]
+-- Arg (-34.0) (-10.0)
 data Arg a b = Arg
   a
   -- ^ The argument used for comparisons in 'Eq' and 'Ord'.
@@ -310,13 +358,23 @@
   )
 
 -- |
+-- ==== __Examples__
+--
 -- >>> Min (Arg 0 ()) <> Min (Arg 1 ())
 -- Min {getMin = Arg 0 ()}
+--
+-- >>> minimum [ Arg (length name) name | name <- ["violencia", "lea", "pixie"]]
+-- Arg 3 "lea"
 type ArgMin a b = Min (Arg a b)
 
 -- |
+-- ==== __Examples__
+--
 -- >>> Max (Arg 0 ()) <> Max (Arg 1 ())
 -- Max {getMax = Arg 1 ()}
+--
+-- >>> maximum [ Arg (length name) name | name <- ["violencia", "lea", "pixie"]]
+-- Arg 9 "violencia"
 type ArgMax a b = Max (Arg a b)
 
 -- | @since 4.9.0.0
@@ -364,6 +422,13 @@
 -- The latter returns the first non-'Nothing',
 -- thus @Data.Monoid.First Nothing <> x = x@.
 --
+-- ==== __Examples__
+--
+-- >>> First 0 <> First 10
+-- First 0
+--
+-- >>> sconcat $ First 1 :| [ First n | n <- [2 ..] ]
+-- First 1
 newtype First a = First { getFirst :: a }
   deriving ( Bounded  -- ^ @since 4.9.0.0
            , Eq       -- ^ @since 4.9.0.0
@@ -427,6 +492,13 @@
 -- The latter returns the last non-'Nothing',
 -- thus @x <> Data.Monoid.Last Nothing = x@.
 --
+-- ==== __Examples__
+--
+-- >>> Last 0 <> Last 10
+-- Last {getLast = 10}
+--
+-- >>> sconcat $ Last 1 :| [ Last n | n <- [2..]]
+-- Last {getLast = * hangs forever *
 newtype Last a = Last { getLast :: a }
   deriving ( Bounded  -- ^ @since 4.9.0.0
            , Eq       -- ^ @since 4.9.0.0
@@ -526,7 +598,7 @@
 --
 -- > mtimesDefault n a = a <> a <> ... <> a  -- using <> (n-1) times
 --
--- In many cases, `stimes 0 a` for a `Monoid` will produce `mempty`.
+-- In many cases, @'stimes' 0 a@ for a `Monoid` will produce `mempty`.
 -- However, there are situations when it cannot do so. In particular,
 -- the following situation is fairly common:
 --
@@ -535,6 +607,7 @@
 --
 -- class Constraint1 a
 -- class Constraint1 a => Constraint2 a
+-- @
 --
 -- @
 -- instance Constraint1 a => 'Semigroup' (T a)
@@ -548,6 +621,14 @@
 -- 'Semigroup' instances, @mtimesDefault@ should be used when the
 -- multiplier might be zero. It is implemented using 'stimes' when
 -- the multiplier is nonzero and 'mempty' when it is zero.
+--
+-- ==== __Examples__
+--
+-- >>> mtimesDefault 0 "bark"
+-- []
+--
+-- >>> mtimesDefault 3 "meow"
+-- "meowmeowmeow"
 mtimesDefault :: (Integral b, Monoid a) => b -> a -> a
 mtimesDefault n x
   | n == 0    = mempty
diff --git a/Data/Semigroup/Internal.hs b/Data/Semigroup/Internal.hs
--- a/Data/Semigroup/Internal.hs
+++ b/Data/Semigroup/Internal.hs
@@ -40,7 +40,7 @@
 
 -- | This is a valid definition of 'stimes' for an idempotent 'Monoid'.
 --
--- When @mappend x x = x@, this definition should be preferred, because it
+-- When @x <> x = x@, this definition should be preferred, because it
 -- works in \(\mathcal{O}(1)\) rather than \(\mathcal{O}(\log n)\)
 stimesIdempotentMonoid :: (Integral b, Monoid a) => b -> a -> a
 stimesIdempotentMonoid n x = case compare n 0 of
@@ -105,9 +105,17 @@
     rep i = x ++ rep (i - 1)
 
 -- | The dual of a 'Monoid', obtained by swapping the arguments of 'mappend'.
+-- | The dual of a 'Monoid', obtained by swapping the arguments of '(<>)'.
 --
--- >>> getDual (mappend (Dual "Hello") (Dual "World"))
--- "WorldHello"
+-- > Dual a <> Dual b == Dual (b <> a)
+--
+-- ==== __Examples__
+--
+-- >>> Dual "Hello" <> Dual "World"
+-- Dual {getDual = "WorldHello"}
+--
+-- >>> Dual (Dual "Hello") <> Dual (Dual "World")
+-- Dual {getDual = Dual {getDual = "HelloWorld"}}
 newtype Dual a = Dual { getDual :: a }
         deriving ( Eq       -- ^ @since 2.01
                  , Ord      -- ^ @since 2.01
@@ -142,9 +150,17 @@
 
 -- | The monoid of endomorphisms under composition.
 --
+-- > Endo f <> Endo g == Endo (f . g)
+--
+-- ==== __Examples__
+--
 -- >>> let computation = Endo ("Hello, " ++) <> Endo (++ "!")
 -- >>> appEndo computation "Haskell"
 -- "Hello, Haskell!"
+--
+-- >>> let computation = Endo (*3) <> Endo (+1)
+-- >>> appEndo computation 1
+-- 6
 newtype Endo a = Endo { appEndo :: a -> a }
                deriving ( Generic -- ^ @since 4.7.0.0
                         )
@@ -158,13 +174,20 @@
 instance Monoid (Endo a) where
         mempty = Endo id
 
--- | Boolean monoid under conjunction ('&&').
+-- | Boolean monoid under conjunction '(&&)'.
 --
--- >>> getAll (All True <> mempty <> All False)
--- False
+-- > All x <> All y = All (x && y)
 --
--- >>> getAll (mconcat (map (\x -> All (even x)) [2,4,6,7,8]))
--- False
+-- ==== __Examples__
+--
+-- >>> All True <> mempty <> All False)
+-- All {getAll = False}
+--
+-- >>> mconcat (map (\x -> All (even x)) [2,4,6,7,8])
+-- All {getAll = False}
+--
+-- >>> All True <> mempty
+-- All {getAll = True}
 newtype All = All { getAll :: Bool }
         deriving ( Eq      -- ^ @since 2.01
                  , Ord     -- ^ @since 2.01
@@ -183,13 +206,20 @@
 instance Monoid All where
         mempty = All True
 
--- | Boolean monoid under disjunction ('||').
+-- | Boolean monoid under disjunction '(||)'.
 --
--- >>> getAny (Any True <> mempty <> Any False)
--- True
+-- > Any x <> Any y = Any (x || y)
 --
--- >>> getAny (mconcat (map (\x -> Any (even x)) [2,4,6,7,8]))
--- True
+-- ==== __Examples__
+--
+-- >>> Any True <> mempty <> Any False
+-- Any {getAny = True}
+--
+-- >>> mconcat (map (\x -> Any (even x)) [2,4,6,7,8])
+-- Any {getAny = True}
+--
+-- >>> Any False <> mempty
+-- Any {getAny = False}
 newtype Any = Any { getAny :: Bool }
         deriving ( Eq      -- ^ @since 2.01
                  , Ord     -- ^ @since 2.01
@@ -210,8 +240,15 @@
 
 -- | Monoid under addition.
 --
--- >>> getSum (Sum 1 <> Sum 2 <> mempty)
--- 3
+-- > Sum a <> Sum b = Sum (a + b)
+--
+-- ==== __Examples__
+--
+-- >>> Sum 1 <> Sum 2 <> mempty
+-- Sum {getSum = 3}
+--
+-- >>> mconcat [ Sum n | n <- [3 .. 9]]
+-- Sum {getSum = 42}
 newtype Sum a = Sum { getSum :: a }
         deriving ( Eq       -- ^ @since 2.01
                  , Ord      -- ^ @since 2.01
@@ -251,8 +288,15 @@
 
 -- | Monoid under multiplication.
 --
--- >>> getProduct (Product 3 <> Product 4 <> mempty)
--- 12
+-- > Product x <> Product y == Product (x * y)
+--
+-- ==== __Examples__
+--
+-- >>> Product 3 <> Product 4 <> mempty
+-- Product {getProduct = 12}
+--
+-- >>> mconcat [ Product n | n <- [2 .. 10]]
+-- Product {getProduct = 3628800}
 newtype Product a = Product { getProduct :: a }
         deriving ( Eq       -- ^ @since 2.01
                  , Ord      -- ^ @since 2.01
@@ -294,11 +338,14 @@
 
 -- | Monoid under '<|>'.
 --
--- >>> getAlt (Alt (Just 12) <> Alt (Just 24))
--- Just 12
+-- > Alt l <> Alt r == Alt (l <|> r)
 --
--- >>> getAlt $ Alt Nothing <> Alt (Just 24)
--- Just 24
+-- ==== __Examples__
+-- >>> Alt (Just 12) <> Alt (Just 24)
+-- Alt {getAlt = Just 12}
+--
+-- >>> Alt Nothing <> Alt (Just 24)
+-- Alt {getAlt = Just 24}
 --
 -- @since 4.8.0.0
 newtype Alt f a = Alt {getAlt :: f a}
diff --git a/GHC/Base.hs b/GHC/Base.hs
--- a/GHC/Base.hs
+++ b/GHC/Base.hs
@@ -250,8 +250,16 @@
 class Semigroup a where
         -- | An associative operation.
         --
+        -- ==== __Examples__
+        --
         -- >>> [1,2,3] <> [4,5,6]
         -- [1,2,3,4,5,6]
+        --
+        -- >>> Just [1, 2, 3] <> Just [4, 5, 6]
+        -- Just [1,2,3,4,5,6]
+        --
+        -- >>> putStr "Hello, " <> putStrLn "World!"
+        -- Hello, World!
         (<>) :: a -> a -> a
         a <> b = sconcat (a :| [ b ])
 
@@ -260,9 +268,20 @@
         -- The default definition should be sufficient, but this can be
         -- overridden for efficiency.
         --
+        -- ==== __Examples__
+        --
+        -- For the following examples, we will assume that we have:
+        --
         -- >>> import Data.List.NonEmpty (NonEmpty (..))
+        --
         -- >>> sconcat $ "Hello" :| [" ", "Haskell", "!"]
         -- "Hello Haskell!"
+        --
+        -- >>> sconcat $ Just [1, 2, 3] :| [Nothing, Just [4, 5, 6]]
+        -- Just [1,2,3,4,5,6]
+        --
+        -- >>> sconcat $ Left 1 :| [Right 2, Left 3, Right 4]
+        -- Right 2
         sconcat :: NonEmpty a -> a
         sconcat (a :| as) = go a as where
           go b (c:cs) = b <> go c cs
@@ -270,17 +289,25 @@
 
         -- | Repeat a value @n@ times.
         --
-        -- Given that this works on a 'Semigroup' it is allowed to fail if
-        -- you request 0 or fewer repetitions, and the default definition
-        -- will do so.
+        -- The default definition will raise an exception for a multiplier that is @<= 0@.
+        -- This may be overridden with an implementation that is total. For monoids
+        -- it is preferred to use 'stimesMonoid'.
         --
         -- By making this a member of the class, idempotent semigroups
         -- and monoids can upgrade this to execute in \(\mathcal{O}(1)\) by
         -- picking @stimes = 'Data.Semigroup.stimesIdempotent'@ or @stimes =
-        -- 'stimesIdempotentMonoid'@ respectively.
+        -- 'Data.Semigroup.stimesIdempotentMonoid'@ respectively.
         --
+        -- ==== __Examples__
+        --
         -- >>> stimes 4 [1]
         -- [1,1,1,1]
+        --
+        -- >>> stimes 5 (putStr "hi!")
+        -- hi!hi!hi!hi!hi!
+        --
+        -- >>> stimes 3 (Right ":)")
+        -- Right ":)"
         stimes :: Integral b => b -> a -> a
         stimes = stimesDefault
 
@@ -314,8 +341,12 @@
 class Semigroup a => Monoid a where
         -- | Identity of 'mappend'
         --
+        -- ==== __Examples__
         -- >>> "Hello world" <> mempty
         -- "Hello world"
+        --
+        -- >>> mempty <> [1, 2, 3]
+        -- [1,2,3]
         mempty :: a
         mempty = mconcat []
         {-# INLINE mempty #-}
diff --git a/GHC/IO/Handle/Text.hs b/GHC/IO/Handle/Text.hs
--- a/GHC/IO/Handle/Text.hs
+++ b/GHC/IO/Handle/Text.hs
@@ -174,16 +174,28 @@
 
 -- | Computation 'hGetLine' @hdl@ reads a line from the file or
 -- channel managed by @hdl@.
+-- 'hGetLine' does not return the newline as part of the result.
 --
+-- A line is separated by the newline
+-- set with 'System.IO.hSetNewlineMode' or 'nativeNewline' by default.
+-- The read newline character(s) are not returned as part of the result.
+--
+-- If 'hGetLine' encounters end-of-file at any point while reading
+-- in the middle of a line, it is treated as a line terminator and the (partial)
+-- line is returned.
+--
 -- This operation may fail with:
 --
 --  * 'isEOFError' if the end of file is encountered when reading
 --    the /first/ character of the line.
 --
--- If 'hGetLine' encounters end-of-file at any other point while reading
--- in a line, it is treated as a line terminator and the (partial)
--- line is returned.
-
+-- ==== __Examples__
+--
+-- >>> withFile "/home/user/foo" ReadMode hGetLine >>= putStrLn
+-- this is the first line of the file :O
+--
+-- >>> withFile "/home/user/bar" ReadMode (replicateM 3 . hGetLine)
+-- ["this is the first line","this is the second line","this is the third line"]
 hGetLine :: Handle -> IO String
 hGetLine h =
   wantReadableHandle_ "hGetLine" h $ \ handle_ ->
diff --git a/GHC/JS/Prim.hs b/GHC/JS/Prim.hs
--- a/GHC/JS/Prim.hs
+++ b/GHC/JS/Prim.hs
@@ -277,13 +277,13 @@
 foreign import javascript unsafe "(($1) => { return ($1 === undefined); })"
   js_isUndefined :: JSVal -> Bool
 
-foreign import javascript unsafe "(($1) => { return ($r = typeof($1) === 'number' ? ($1|0) : 0;); })"
+foreign import javascript unsafe "(($1) => { return (typeof($1) === 'number' ? ($1|0) : 0); })"
   js_fromJSInt :: JSVal -> Int
 
-foreign import javascript unsafe "(($1) => { return ($r = $1;); })"
+foreign import javascript unsafe "(($1) => { return $1; })"
   js_toJSInt :: Int -> JSVal
 
-foreign import javascript unsafe "$r = null;"
+foreign import javascript unsafe "(() => { return null; })"
   js_null :: JSVal
 
 foreign import javascript unsafe "(($1,$2) => { return $1[h$fromHsString($2)]; })"
@@ -306,7 +306,6 @@
 
 foreign import javascript unsafe "(($1_1,$1_2) => { return h$decodeUtf8z($1_1, $1_2); })"
   js_unpackJSStringUtf8## :: Addr# -> State# s -> (# State# s, JSVal# #)
-
 
 foreign import javascript unsafe "(($1_1, $1_2) => { return h$decodeUtf8z($1_1,$1_2); })"
   js_unsafeUnpackJSStringUtf8## :: Addr# -> JSVal#
diff --git a/base.cabal b/base.cabal
--- a/base.cabal
+++ b/base.cabal
@@ -1,19 +1,24 @@
 cabal-version:  3.0
 name:           base
-version:        4.18.2.0
+version:        4.18.2.1
 -- NOTE: Don't forget to update ./changelog.md
 
 license:        BSD-3-Clause
 license-file:   LICENSE
-maintainer:     libraries@haskell.org
-bug-reports:    https://gitlab.haskell.org/ghc/ghc/issues/new
-synopsis:       Basic libraries
+maintainer:     Core Libraries Committee <core-libraries-committee@haskell.org>
+bug-reports:    https://github.com/haskell/core-libraries-committee/issues
+synopsis:       Core data structures and operations
 category:       Prelude
 build-type:     Configure
-description:
-    This package contains the Standard Haskell "Prelude" and its support libraries,
-    and a large collection of useful libraries ranging from data
-    structures to parsing combinators and debugging utilities.
+description:    Haskell's base library provides, among other things, core types (e.g. [Bool]("Data.Bool") and [Int]("Data.Int")),
+                data structures (e.g. [List]("Data.List"), [Tuple]("Data.Tuple") and [Maybe]("Data.Maybe")),
+                the [Exception]("Control.Exception") mechanism, and the [IO]("System.IO") & [Concurrency]("Control.Concurrent") operations.
+                The "Prelude" module, which is imported by default, exposes a curated set of types and functions from other modules.
+
+                Other data structures like [Map](https://hackage.haskell.org/package/containers/docs/Data-Map.html),
+                [Set](https://hackage.haskell.org/package/containers/docs/Data-Set.html) are available in the [containers](https://hackage.haskell.org/package/containers) library.
+                To work with textual data, use the [text](https://hackage.haskell.org/package/text/docs/Data-Text.html) library.
+
 
 extra-tmp-files:
     autom4te.cache
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,8 @@
 # Changelog for [`base` package](http://hackage.haskell.org/package/base)
 
+## 4.18.2.1 *April 2024*
+  * Various documentation improvements
+
 ## 4.18.2.0 *January 2024*
   * Update to [Unicode 15.1.0](https://www.unicode.org/versions/Unicode15.1.0/).
   * Improve String & IsString documentation.
