diff --git a/ascii-char.cabal b/ascii-char.cabal
--- a/ascii-char.cabal
+++ b/ascii-char.cabal
@@ -1,7 +1,7 @@
 cabal-version: 3.0
 
 name: ascii-char
-version: 1.0.0.17
+version: 1.0.1.0
 synopsis: A Char type representing an ASCII character
 category: Data, Text
 
@@ -18,7 +18,7 @@
 homepage: https://github.com/typeclasses/ascii-char
 bug-reports: https://github.com/typeclasses/ascii-char/issues
 
-extra-doc-files: *.md
+extra-source-files: *.md
 
 source-repository head
     type: git
@@ -36,7 +36,6 @@
 
 library
     import: base
-    ghc-options: -fno-warn-unused-imports
     hs-source-dirs: library
 
     default-extensions:
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,8 +1,8 @@
-### 1.0.0.17 (2022-12-30)
+### 1.0.1.0 (2023-01-05)
 
-Fix error in cabal file (change `extra-source-files` to `extra-doc-files`)
+Add `Word8` conversions: `toWord8`, `fromWord8Maybe`, `fromWord8Unsafe`
 
-### 1.0.0.16 (2022-12-27)
+### 1.0.0.16 (2022-10-04)
 
 Test suite now uses `hspec`
 
diff --git a/library/ASCII/Char.hs b/library/ASCII/Char.hs
--- a/library/ASCII/Char.hs
+++ b/library/ASCII/Char.hs
@@ -1,95 +1,178 @@
-{- |
-
-The 'Char' type has 128 nullary constructors, listed in order according to each character's 7-bit numeric code.
-
--}
-
+{-| The 'Char' type has 128 nullary constructors, listed in
+    order according to each character's 7-bit numeric code. -}
 module ASCII.Char
   (
     {- * The @Char@ type -} Char (..),
-    {- * Conversions with @Int@ -} toInt, fromIntMaybe, fromIntUnsafe,
-    {- * Enumeration -} allCharacters
+    {- * @Int@ -} toInt, fromIntMaybe, fromIntUnsafe,
+    {- * @Word8@ -} toWord8, fromWord8Maybe, fromWord8Unsafe,
+    {- * Enumeration -} allCharacters,
     {- * Notes -} {- $notes -}
   )
   where
 
 import Data.Bool (otherwise)
 import Data.Data (Data)
-import Data.Eq (Eq, (/=), (==))
+import Data.Eq (Eq)
 import Data.Hashable (Hashable)
 import Data.Int (Int)
 import Data.Maybe (Maybe (..))
 import Data.Ord (Ord, (<), (>))
+import Data.Word (Word8)
 import GHC.Generics (Generic)
-import Prelude (Bounded, Enum, enumFromTo, fromEnum, maxBound, minBound, toEnum)
+import Prelude (Bounded, Enum, enumFromTo, fromEnum, fromIntegral, maxBound, minBound, toEnum)
 import Text.Show (Show)
 
-import qualified Data.Char as C
-
--- | A character in the ASCII character set.
+-- | A character in the ASCII character set
 
 data Char =
-      Null | StartOfHeading | StartOfText | EndOfText | EndOfTransmission | Enquiry | Acknowledgement | Bell | Backspace | HorizontalTab | LineFeed | VerticalTab | FormFeed | CarriageReturn | ShiftOut | ShiftIn | DataLinkEscape
+      Null | StartOfHeading | StartOfText | EndOfText | EndOfTransmission | Enquiry
+    | Acknowledgement | Bell | Backspace | HorizontalTab | LineFeed | VerticalTab
+    | FormFeed | CarriageReturn | ShiftOut | ShiftIn | DataLinkEscape
 
     | DeviceControl1 | DeviceControl2 | DeviceControl3 | DeviceControl4
 
-    | NegativeAcknowledgement | SynchronousIdle | EndOfTransmissionBlock | Cancel | EndOfMedium | Substitute | Escape
+    | NegativeAcknowledgement | SynchronousIdle | EndOfTransmissionBlock
+    | Cancel | EndOfMedium | Substitute | Escape
 
     | FileSeparator | GroupSeparator | RecordSeparator | UnitSeparator
 
-    | Space | ExclamationMark | QuotationMark | NumberSign | DollarSign | PercentSign | Ampersand | Apostrophe | LeftParenthesis | RightParenthesis | Asterisk | PlusSign | Comma | HyphenMinus | FullStop | Slash
+    | Space
+    | ExclamationMark  -- ^ !
+    | QuotationMark    -- ^ "
+    | NumberSign       -- ^ #
+    | DollarSign       -- ^ $
+    | PercentSign      -- ^ %
+    | Ampersand        -- ^ &
+    | Apostrophe       -- ^ #
+    | LeftParenthesis  -- ^ (
+    | RightParenthesis -- ^ )
+    | Asterisk         -- ^ \*
+    | PlusSign         -- ^ +
+    | Comma            -- ^ ,
+    | HyphenMinus      -- ^ \-
+    | FullStop         -- ^ .
+    | Slash            -- ^ /
 
     | Digit0 | Digit1 | Digit2 | Digit3 | Digit4 | Digit5 | Digit6 | Digit7 | Digit8 | Digit9
 
-    | Colon | Semicolon | LessThanSign | EqualsSign | GreaterThanSign | QuestionMark | AtSign
+    | Colon            -- ^ :
+    | Semicolon        -- ^ ;
+    | LessThanSign     -- ^ \<
+    | EqualsSign       -- ^ =
+    | GreaterThanSign  -- ^ \>
+    | QuestionMark     -- ^ ?
+    | AtSign           -- ^ \@
 
-    | CapitalLetterA | CapitalLetterB | CapitalLetterC | CapitalLetterD | CapitalLetterE | CapitalLetterF | CapitalLetterG | CapitalLetterH | CapitalLetterI | CapitalLetterJ | CapitalLetterK | CapitalLetterL | CapitalLetterM | CapitalLetterN | CapitalLetterO | CapitalLetterP | CapitalLetterQ | CapitalLetterR | CapitalLetterS | CapitalLetterT | CapitalLetterU | CapitalLetterV | CapitalLetterW | CapitalLetterX | CapitalLetterY | CapitalLetterZ
+    | CapitalLetterA | CapitalLetterB | CapitalLetterC | CapitalLetterD | CapitalLetterE
+    | CapitalLetterF | CapitalLetterG | CapitalLetterH | CapitalLetterI | CapitalLetterJ
+    | CapitalLetterK | CapitalLetterL | CapitalLetterM | CapitalLetterN | CapitalLetterO
+    | CapitalLetterP | CapitalLetterQ | CapitalLetterR | CapitalLetterS | CapitalLetterT
+    | CapitalLetterU | CapitalLetterV | CapitalLetterW | CapitalLetterX | CapitalLetterY
+    | CapitalLetterZ
 
-    | LeftSquareBracket | Backslash | RightSquareBracket | Caret | Underscore | GraveAccent
+    | LeftSquareBracket  -- ^ \[
+    | Backslash          -- ^ \\
+    | RightSquareBracket -- ^ \]
+    | Caret              -- ^ \^
+    | Underscore         -- ^ _
+    | GraveAccent        -- ^ \`
 
-    | SmallLetterA | SmallLetterB | SmallLetterC | SmallLetterD | SmallLetterE | SmallLetterF | SmallLetterG | SmallLetterH | SmallLetterI | SmallLetterJ | SmallLetterK | SmallLetterL | SmallLetterM | SmallLetterN | SmallLetterO | SmallLetterP | SmallLetterQ | SmallLetterR | SmallLetterS | SmallLetterT | SmallLetterU | SmallLetterV | SmallLetterW | SmallLetterX | SmallLetterY | SmallLetterZ
+    | SmallLetterA | SmallLetterB | SmallLetterC | SmallLetterD | SmallLetterE
+    | SmallLetterF | SmallLetterG | SmallLetterH | SmallLetterI | SmallLetterJ
+    | SmallLetterK | SmallLetterL | SmallLetterM | SmallLetterN | SmallLetterO
+    | SmallLetterP | SmallLetterQ | SmallLetterR | SmallLetterS | SmallLetterT
+    | SmallLetterU | SmallLetterV | SmallLetterW | SmallLetterX | SmallLetterY
+    | SmallLetterZ
 
-    | LeftCurlyBracket | VerticalLine | RightCurlyBracket | Tilde | Delete
+    | LeftCurlyBracket   -- ^ \{
+    | VerticalLine       -- ^ \|
+    | RightCurlyBracket  -- ^ \}
+    | Tilde              -- ^ \~
+    | Delete
 
--- | ASCII characters can be compared for equality using '(==)'. Comparisons are case-sensitive; @'SmallLetterA' '/=' 'CapitalLetterA'@.
+{-| ASCII characters can be compared for equality using '(==)'.
+Comparisons are case-sensitive; @'SmallLetterA' '/=' 'CapitalLetterA'@. -}
 deriving stock instance Eq Char
 
--- | ASCII characters are ordered; for example, the letter /A/ is "less than" ('<') the letter /B/ because it appears earlier in the list. The ordering of ASCII characters is the same as the ordering of the corresponding Unicode 'C.Char's.
+{-| ASCII characters are ordered; for example, the letter /A/ is "less than"
+('<') the letter /B/ because it appears earlier in the list. The ordering of
+ASCII characters is the same as the ordering of the corresponding Unicode
+'Data.Char.Char's. -}
+
 deriving stock instance Ord Char
 
--- | The 'Enum' instance allows us to use range syntax, for example @['SmallLetterA' .. 'SmallLetterZ']@ is a list all lower-case letters from /a/ to /z/. Instead of 'toEnum' and 'fromEnum', consider using 'toInt' and 'fromIntMaybe'.
+{-| The 'Enum' instance allows us to use range syntax, for example
+@['SmallLetterA' .. 'SmallLetterZ']@ is a list all lower-case letters from /a/
+to /z/. Instead of 'toEnum' and 'fromEnum', consider using 'toInt' and
+'fromIntMaybe'. -}
 deriving stock instance Enum Char
 
--- | The least character is 'Null', and the greatest character is 'Delete'. You can write @(['minBound' .. 'maxBound'] :: [ASCII.'Char'])@ to get a list of all the ASCII characters.
+{-| The least character is 'Null', and the greatest character is 'Delete'. You
+can write @(['minBound' .. 'maxBound'] :: [ASCII.'Char'])@ to get a list of all
+the ASCII characters. -}
 deriving stock instance Bounded Char
 
--- | 'show' produces the name of a constructor. For example, the character @e@ is shown as “@SmallLetterE@”. See "ASCII.Char" for the complete list of constructor names.
+{-| 'show' produces the name of a constructor. For example, the character @e@ is
+shown as “@SmallLetterE@”. See "ASCII.Char" for the complete list of constructor
+names. -}
 deriving stock instance Show Char
 
--- | The 'Data' instance allows ASCII characters to be used with generic programming in the “SYB” style. (See the <https://hackage.haskell.org/package/syb syb> package and the 2003 paper <https://www.microsoft.com/en-us/research/wp-content/uploads/2003/01/hmap.pdf Scrap Your Boilerplate> by Ralf Lämmel and Simon Peyton Jones.)
+{-| The 'Data' instance allows ASCII characters to be used with generic
+programming in the “SYB” style. (See the
+<https://hackage.haskell.org/package/syb syb> package and the 2003 paper
+<https://www.microsoft.com/en-us/research/wp-content/uploads/2003/01/hmap.pdf Scrap Your Boilerplate>
+by Ralf Lämmel and Simon Peyton Jones.) -}
 deriving stock instance Data Char
 
--- | The 'Generic' instance allows ASCII characters to be used with generic programming in the “generic deriving” style. (See the <https://hackage.haskell.org/package/generic-data generic-data> package and the 2010 paper <http://dreixel.net/research/pdf/gdmh.pdf A generic deriving mechanism for Haskell> by José Pedro Magalhães, Atze Dijkstra, Johan Jeuring, and Andres Löh.)
+{-| The 'Generic' instance allows ASCII characters to be used with generic
+programming in the “generic deriving” style. (See the
+<https://hackage.haskell.org/package/generic-data generic-data> package and the 2010 paper
+<http://dreixel.net/research/pdf/gdmh.pdf A generic deriving mechanism for Haskell>
+by José Pedro Magalhães, Atze Dijkstra, Johan Jeuring, and Andres Löh.) -}
 deriving stock instance Generic Char
 
--- | The 'Hashable' instance lets us collect ASCII characters in hash-based sets, and it lets us use ASCII characters as keys in hash-based maps. (See the @unordered-containers@ package.)
+{-| The 'Hashable' instance lets us collect ASCII characters in hash-based sets,
+and it lets us use ASCII characters as keys in hash-based maps. (See the
+@unordered-containers@ package.) -}
 deriving anyclass instance Hashable Char
 
-{- | Converts an ASCII character to its corresponding numeric value between 0 and 127.
+{-| Converts an ASCII character to its corresponding numeric value between 0 and 127
 
->>> map toInt [Null, CapitalLetterA, SmallLetterA, Delete]
-[0,65,97,127]
+@
+toInt Null == 0
+toInt CapitalLetterA == 6
+toInt SmallLetterA == 97
+toInt Delete == 127
+@
 
 -}
 
 toInt :: Char -> Int
 toInt = Prelude.fromEnum
 
-{- | Returns 'Just' the ASCII character corresponding to a numeric value between 0 and 127, or 'Nothing' for numbers outside this range.
+{-| Converts an ASCII character to its corresponding byte between 0 and 127
 
->>> map fromIntMaybe [-1, 0, 65, 127, 128]
-[Nothing,Just Null,Just CapitalLetterA,Just Delete,Nothing]
+@
+toWord8 Null == 0
+toWord8 CapitalLetterA == 6
+toWord8 SmallLetterA == 97
+toWord8 Delete == 127
+@
+-}
+toWord8 :: Char -> Word8
+toWord8 x = Prelude.fromIntegral (Prelude.fromEnum x)
 
+{-| Returns 'Just' the ASCII character corresponding to a numeric value between
+    0 and 127, or 'Nothing' for numbers outside this range
+
+@
+fromIntMaybe (-1) == Nothing
+fromIntMaybe 0 == Just Null
+fromIntMaybe 65 == Just CapitalLetterA
+fromIntMaybe 127 == Just Delete
+fromIntMaybe 128 == Nothing
+@
+
 -}
 
 fromIntMaybe :: Int -> Maybe Char
@@ -97,18 +180,55 @@
                | x > 127   = Nothing
                | otherwise = Just (fromIntUnsafe x)
 
-{- | The inverse of 'toInt'.
+{-| Returns 'Just' the ASCII character corresponding to a byte between
+    0 and 127, or 'Nothing' for bytes above this range
 
-This is marked as /unsafe/ because it is undefined for numbers below 0 or above 127. The safe variant of this function is 'fromIntMaybe'.
+@
+fromWord8Maybe 0 == Just Null
+fromWord8Maybe 65 == Just CapitalLetterA
+fromWord8Maybe 127 == Just Delete
+fromWord8Maybe 128 == Nothing
+@
 
->>> map fromIntUnsafe [65, 66, 67]
-[CapitalLetterA,CapitalLetterB,CapitalLetterC]
+-}
+fromWord8Maybe :: Word8 -> Maybe Char
+fromWord8Maybe x | x > 127   = Nothing
+                 | otherwise = Just (fromWord8Unsafe x)
 
+{-| The inverse of 'toInt'
+
+This is marked as /unsafe/ because it is undefined for numbers below 0
+or above 127. The safe variant of this function is 'fromIntMaybe'.
+
+@
+fromIntUnsafe (-1) == undefined
+fromIntUnsafe 65 == CapitalLetterA
+fromIntUnsafe 66 == CapitalLetterB
+fromIntUnsafe 67 == CapitalLetterC
+fromIntUnsafe 128 == undefined
+@
+
 -}
 
 fromIntUnsafe :: Int -> Char
 fromIntUnsafe = Prelude.toEnum
 
+{-| The inverse of 'toWord8'
+
+This is marked as /unsafe/ because it is undefined bytes above 127.
+The safe variant of this function is 'fromWord8Maybe'.
+
+@
+fromWord8Unsafe 65 == CapitalLetterA
+fromWord8Unsafe 66 == CapitalLetterB
+fromWord8Unsafe 67 == CapitalLetterC
+fromWord8Unsafe 128 == undefined
+@
+
+-}
+fromWord8Unsafe :: Word8 -> Char
+fromWord8Unsafe x = fromIntUnsafe (Prelude.fromIntegral x)
+
 allCharacters :: [Char]
 allCharacters = Prelude.enumFromTo Prelude.minBound Prelude.maxBound
 
@@ -116,17 +236,20 @@
 
 There are 128 characters in total.
 
->>> length allCharacters
-128
+@
+length allCharacters == 128
+@
 
 Null is the first character.
 
->>> minBound :: Char
-Null
+@
+minBound == Null
+@
 
 Delete is the last character.
 
->>> maxBound :: Char
-Delete
+@
+maxBound == Delete
+@
 
 -}
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -3,39 +3,72 @@
 import ASCII.Char
 
 import Data.Function (($))
-import Data.List (length)
+import Data.List (length, sort)
 import Data.Maybe (Maybe (..))
 import Prelude (maxBound, minBound)
 import System.IO (IO)
-import Test.Hspec (hspec, it, shouldBe)
+import Test.Hspec (describe, hspec, it, shouldBe)
 
 main :: IO ()
 main = hspec $ do
 
-    it "toInt" $ do
-        let f = toInt
-        f Null `shouldBe` 0
-        f CapitalLetterA `shouldBe` 65
-        f SmallLetterA `shouldBe` 97
-        f Delete `shouldBe` 127
+    describe "toInt" $ do
+        let c ~> n = toInt c `shouldBe` n
 
-    it "fromIntMaybe" $ do
-        let f = fromIntMaybe
-        f (-1) `shouldBe` Nothing
-        f 0 `shouldBe` Just Null
-        f 65 `shouldBe` Just CapitalLetterA
-        f 127 `shouldBe` Just Delete
-        f 128 `shouldBe` Nothing
+        it "Null   → 0"   $ Null           ~> 0
+        it "A      → 65"  $ CapitalLetterA ~> 65
+        it "a      → 97"  $ SmallLetterA   ~> 97
+        it "Delete → 127" $ Delete         ~> 127
 
-    it "fromIntUnsafe" $ do
-        let f = fromIntUnsafe
-        f 65 `shouldBe` CapitalLetterA
-        f 66 `shouldBe` CapitalLetterB
-        f 67 `shouldBe` CapitalLetterC
+    describe "toWord8" $ do
+        let c ~> n = toWord8 c `shouldBe` n
 
-    it "allCharacters" $ do
-        length allCharacters `shouldBe` 128
+        it "Null   → 0"   $ Null           ~> 0
+        it "A      → 65"  $ CapitalLetterA ~> 65
+        it "a      → 97"  $ SmallLetterA   ~> 97
+        it "Delete → 127" $ Delete         ~> 127
 
-    it "Bounded" $ do
-        minBound `shouldBe` Null
-        maxBound `shouldBe` Delete
+    describe "fromIntMaybe" $ do
+        let n ~> c = fromIntMaybe n `shouldBe` c
+
+        it "-1  → Nothing" $ (-1) ~> Nothing
+        it "0   → Null"    $ 0    ~> Just Null
+        it "65  → A"       $ 65   ~> Just CapitalLetterA
+        it "127 → Delete"  $ 127  ~> Just Delete
+        it "128 → Nothing" $ 128  ~> Nothing
+
+    describe "fromWord8Maybe" $ do
+        let n ~> c = fromWord8Maybe n `shouldBe` c
+
+        it "0   → Null"    $ 0    ~> Just Null
+        it "65  → A"       $ 65   ~> Just CapitalLetterA
+        it "127 → Delete"  $ 127  ~> Just Delete
+        it "128 → Nothing" $ 128  ~> Nothing
+
+    describe "fromIntUnsafe" $ do
+        let n ~> c = fromIntUnsafe n `shouldBe` c
+
+        it "0  → Null"    $ 0  ~> Null
+        it "65 → A"       $ 65 ~> CapitalLetterA
+        it "66 → B"       $ 66 ~> CapitalLetterB
+        it "67 → C"       $ 67 ~> CapitalLetterC
+        it "127 → Delete" $ 127  ~> Delete
+
+    describe "fromWord8Unsafe" $ do
+        let n ~> c = fromWord8Unsafe n `shouldBe` c
+
+        it "0  → Null"    $ 0  ~> Null
+        it "65 → A"       $ 65 ~> CapitalLetterA
+        it "66 → B"       $ 66 ~> CapitalLetterB
+        it "67 → C"       $ 67 ~> CapitalLetterC
+        it "127 → Delete" $ 127  ~> Delete
+
+    describe "allCharacters" $ do
+        let x = allCharacters
+
+        it "has 128 items" $ length x `shouldBe` 128
+        it "is sorted"     $ sort x `shouldBe` x
+
+    describe "Bounded" $ do
+        it "min bound is Null"   $ minBound `shouldBe` Null
+        it "max bound is Delete" $ maxBound `shouldBe` Delete
