diff --git a/ASCII.hs b/ASCII.hs
new file mode 100644
--- /dev/null
+++ b/ASCII.hs
@@ -0,0 +1,327 @@
+{- |
+
+The __American Standard Code for Information Interchange__ (ASCII) comprises a set of 128 characters, each represented by 7 bits. 33 of these characters are /'Control' codes/; a few of these are still in use, but most are obsolete relics of the early days of computing. The other 95 are /'Printable' characters/ such as letters and numbers, mostly corresponding to the keys on an American English keyboard.
+
+Nowadays instead of ASCII we typically work with text using an encoding such as UTF-8 that can represent the entire Unicode character set, which includes over a hundred thousand characters and is not limited to the symbols of any particular writing system or culture. However, ASCII is still relevant to network protocols; for example, we can see it in the specification of [HTTP message headers](https://tools.ietf.org/html/rfc7230#section-1.2).
+
+There is a convenient relationship between ASCII and Unicode: the ASCII characters are the first 128 characters of the much larger Unicode character set. The [C0 Controls and Basic Latin](https://www.unicode.org/charts/PDF/U0000.pdf) section of the Unicode standard contains a list of all the ASCII characters. You may also find this list replicated in the "ASCII.Char" module; each ASCII character corresponds to a constructor of the 'ASCII.Char' type.
+
+We do not elaborate on the semantics of the control characters here, because this information is both obsolete and restricted by copyright law. It is described by a document entitled /"Coded Character Sets - 7-Bit American National Standard Code for Information Interchange (7-Bit ASCII)"/, published by American National Standards Institute (ANSI) and available for purchase [on their website](https://webstore.ansi.org/Standards/INCITS/INCITS1986R2012).
+
+-}
+
+module ASCII
+  (
+    {- * @Char@ -} {- $char -} Char,
+
+    {- * Character classifications -}
+    {- ** Print/control groups -} {- $groups -} Group (..), charGroup,  inGroup,
+    {- ** Upper/lower case     -} {- $case   -} Case (..),  letterCase, isCase, toCaseChar, toCaseString,
+
+    {- * Monomorphic conversions -} {- $monomorphicConversions -}
+    {- ** @Int@        -} {- $intConversions           -} charToInt,               intToCharMaybe,               intToCharUnsafe,
+    {- ** @Word8@      -} {- $word8Conversions         -} charToWord8,             word8ToCharMaybe,             word8ToCharUnsafe,
+    {- ** @Char@       -} {- $unicodeCharConversions   -} charToUnicode,           unicodeToCharMaybe,           unicodeToCharUnsafe,
+    {- ** @String@     -} {- $unicodeStringConversions -} charListToUnicodeString, unicodeStringToCharListMaybe, unicodeStringToCharListUnsafe,
+    {- ** @Text@       -} {- $textConversions          -} charListToText,          textToCharListMaybe,          textToCharListUnsafe,
+    {- ** @ByteString@ -} {- $byteStringConversions    -} charListToByteString,    byteStringToCharListMaybe,    byteStringToCharListUnsafe,
+
+    {- * Refinement type -} {- $refinement -} {- ** @ASCII@ -} ASCII,
+
+    {- * Polymorphic conversions -} {- ** Validate -} validateChar, validateString, {- ** Lift -} {- $lift -} lift,
+
+    {- * Classes -} {- ** @CharSuperset@ -} CharSuperset, {- ** @StringSuperset@ -} StringSuperset, {- ** @Lift@ -} Lift, {- ** @CharIso@ -} CharIso, {- ** @StringIso@ -} StringIso,
+
+    {- * Quasi-quoters -} {- ** @char@ -} char, {- ** @string@ -} string
+  )
+  where
+
+import ASCII.Case          ( Case (..) )
+import ASCII.Char          ( Char )
+import ASCII.Group         ( Group (..) )
+import ASCII.Isomorphism   ( CharIso, StringIso )
+import ASCII.Lift          ( Lift )
+import ASCII.QuasiQuoters  ( char, string )
+import ASCII.Refinement    ( ASCII, validateChar, validateString )
+import ASCII.Superset      ( CharSuperset, StringSuperset )
+
+import Control.Monad       ( (>=>) )
+import Data.Bool           ( Bool (..) )
+import Data.Function       ( (.) )
+import Data.Int            ( Int )
+import Data.Maybe          ( Maybe, maybe )
+import Data.Word           ( Word8 )
+
+import qualified  ASCII.Case
+import qualified  ASCII.Group
+import qualified  ASCII.Isomorphism
+import qualified  ASCII.Lift
+import qualified  ASCII.Superset
+
+import qualified  Data.ByteString  as  BS
+import qualified  Data.Char        as  Unicode
+import qualified  Data.String      as  Unicode
+import qualified  Data.Text        as  Text
+
+{- $setup
+
+>>> import ASCII.Char (Char (..))
+>>> import Data.List (map)
+>>> import Data.Text (Text)
+>>> import Data.Word (Word8)
+
+-}
+
+{- $char
+
+See also: "ASCII.Char"
+
+-}
+
+{- $groups
+
+ASCII characters are broadly categorized into two groups: /control codes/ and /printable characters/.
+
+See also: "ASCII.Group"
+
+-}
+
+
+{- | Determine which group a particular character belongs to.
+
+>>> map charGroup [CapitalLetterA,EndOfTransmission]
+[Printable,Control]
+
+-}
+
+charGroup :: CharIso char => char -> Group
+charGroup = ASCII.Group.charGroup . ASCII.Isomorphism.toChar
+
+{- | Test whether a character belongs to a particular ASCII group.
+
+>>> inGroup Printable EndOfTransmission
+False
+
+>>> inGroup Control EndOfTransmission
+True
+
+>>> map (inGroup Printable) ( [-1, 5, 65, 97, 127, 130] :: [Int] )
+[False,False,True,True,False,False]
+
+-}
+
+inGroup :: CharSuperset char => Group -> char -> Bool
+inGroup g = maybe False (ASCII.Group.inGroup g) . ASCII.Superset.toCharMaybe
+
+{- $case
+
+/Case/ is a property of letters. /A-Z/ are /upper case/ letters, and /a-z/ are /lower case/ letters. No other ASCII characters have case.
+
+See also: "ASCII.Case"
+
+-}
+
+{- | Determines whether a character is an ASCII letter, and if so, whether it is upper or lower case.
+
+>>> map letterCase [SmallLetterA, CapitalLetterA, ExclamationMark]
+[Just LowerCase,Just UpperCase,Nothing]
+
+>>> map letterCase ( [string|Hey!|] :: [ASCII Word8] )
+[Just UpperCase,Just LowerCase,Just LowerCase,Nothing]
+
+-}
+
+letterCase :: CharSuperset char => char -> Maybe Case
+letterCase = ASCII.Superset.toCharMaybe >=> ASCII.Case.letterCase
+
+{- | Determines whether a character is an ASCII letter of a particular case.
+
+>>> map (isCase UpperCase) [SmallLetterA, CapitalLetterA, ExclamationMark]
+[False,True,False]
+
+>>> map (isCase UpperCase) ( [string|Hey!|] :: [ASCII Word8] )
+[True,False,False,False]
+
+>>> map (isCase UpperCase) ( [-1, 65, 97, 150] :: [Int] )
+[False,True,False,False]
+
+-}
+
+isCase :: CharSuperset char => Case -> char -> Bool
+isCase c = maybe False (ASCII.Case.isCase c) . ASCII.Superset.toCharMaybe
+
+{- | Maps a letter character to its upper/lower case equivalent.
+
+>>> toCaseChar UpperCase SmallLetterA
+CapitalLetterA
+
+>>> ([char|a|] :: ASCII Word8, toCaseChar UpperCase [char|a|] :: ASCII Word8)
+(asciiUnsafe 97,asciiUnsafe 65)
+
+-}
+
+toCaseChar :: CharIso char => Case -> char -> char
+toCaseChar c = ASCII.Isomorphism.asChar (ASCII.Case.toCase c)
+
+{- | Maps each of the characters in a string to its upper/lower case equivalent.
+
+>>> toCaseString UpperCase [CapitalLetterH,SmallLetterE,SmallLetterY,ExclamationMark]
+[CapitalLetterH,CapitalLetterE,CapitalLetterY,ExclamationMark]
+
+>>> toCaseString UpperCase [string|Hey!|] :: ASCII Text
+asciiUnsafe "HEY!"
+
+-}
+
+toCaseString :: StringIso string => Case -> string -> string
+toCaseString c = ASCII.Isomorphism.mapChars (ASCII.Case.toCase c)
+
+{- $monomorphicConversions
+
+These are a few simple monomorphic functions to convert between ASCII and types representing some other character set.
+
+This is not intended to be an exhaustive list of all possible conversions. For more options, see "ASCII.Superset".
+
+-}
+
+{- $intConversions
+
+These functions convert between the ASCII 'Char' type and 'Int'.
+
+-}
+
+{- |
+
+>>> map charToInt [Null, CapitalLetterA, SmallLetterA, Delete]
+[0,65,97,127]
+
+-}
+
+charToInt :: Char -> Int
+charToInt = ASCII.Superset.fromChar
+
+intToCharMaybe :: Int -> Maybe Char
+intToCharMaybe = ASCII.Superset.toCharMaybe
+
+intToCharUnsafe :: Int -> Char
+intToCharUnsafe = ASCII.Superset.toCharUnsafe
+
+{- $word8Conversions
+
+These functions convert between the ASCII 'Char' type and 'Word8'.
+
+-}
+
+{- |
+
+>>> map charToWord8 [Null, CapitalLetterA, SmallLetterA, Delete]
+[0,65,97,127]
+
+-}
+
+charToWord8 :: Char -> Word8
+charToWord8 = ASCII.Superset.fromChar
+
+word8ToCharMaybe :: Word8 -> Maybe Char
+word8ToCharMaybe = ASCII.Superset.toCharMaybe
+
+word8ToCharUnsafe :: Word8 -> Char
+word8ToCharUnsafe = ASCII.Superset.toCharUnsafe
+
+{- $unicodeCharConversions
+
+These functions convert between the ASCII 'Char' type and the Unicode 'Unicode.Char' type.
+
+-}
+
+charToUnicode :: Char -> Unicode.Char
+charToUnicode = ASCII.Superset.fromChar
+
+unicodeToCharMaybe :: Unicode.Char -> Maybe Char
+unicodeToCharMaybe = ASCII.Superset.toCharMaybe
+
+unicodeToCharUnsafe :: Unicode.Char -> Char
+unicodeToCharUnsafe = ASCII.Superset.toCharUnsafe
+
+{- $unicodeStringConversions
+
+These functions convert between @['Char']@ (a list of ASCII characters) and 'Unicode.String' (a list of Unicode characters).
+
+-}
+
+charListToUnicodeString :: [Char] -> Unicode.String
+charListToUnicodeString = ASCII.Superset.fromCharList
+
+unicodeStringToCharListMaybe :: Unicode.String -> Maybe [Char]
+unicodeStringToCharListMaybe = ASCII.Superset.toCharListMaybe
+
+unicodeStringToCharListUnsafe :: Unicode.String -> [Char]
+unicodeStringToCharListUnsafe = ASCII.Superset.toCharListUnsafe
+
+{- $textConversions
+
+These functions convert between @['Char']@ and 'Text.Text'.
+
+-}
+
+{- |
+
+>>> charListToText [CapitalLetterH,SmallLetterI,ExclamationMark]
+"Hi!"
+
+-}
+
+charListToText :: [Char] -> Text.Text
+charListToText = ASCII.Superset.fromCharList
+
+textToCharListMaybe :: Text.Text -> Maybe [Char]
+textToCharListMaybe = ASCII.Superset.toCharListMaybe
+
+textToCharListUnsafe :: Text.Text -> [Char]
+textToCharListUnsafe = ASCII.Superset.toCharListUnsafe
+
+{- $byteStringConversions
+
+These functions convert between @['Char']@ and 'BS.ByteString'.
+
+-}
+
+charListToByteString :: [Char] -> BS.ByteString
+charListToByteString = ASCII.Superset.fromCharList
+
+byteStringToCharListMaybe :: BS.ByteString -> Maybe [Char]
+byteStringToCharListMaybe = ASCII.Superset.toCharListMaybe
+
+byteStringToCharListUnsafe :: BS.ByteString -> [Char]
+byteStringToCharListUnsafe = ASCII.Superset.toCharListUnsafe
+
+{- $refinement
+
+See also: "ASCII.Refinement"
+
+-}
+
+{- $lift
+
+See also: "ASCII.Lift"
+
+-}
+
+{- | Converts from ASCII to any larger type.
+
+For example, @(lift \@ASCII.Char \@Word8)@ is the same function as 'charToWord8'.
+
+>>> lift CapitalLetterA :: Word8
+65
+
+And @(lift \@[ASCII.Char] \@Text)@ is equivalent to 'charListToText'.
+
+>>> lift [CapitalLetterH,SmallLetterI,ExclamationMark] :: Text
+"Hi!"
+
+Due to the highly polymorphic nature of the 'lift' function, often it must used with an explicit type signature or type application to avoid any type ambiguity.
+
+-}
+
+lift :: Lift ascii superset => ascii -> superset
+lift = ASCII.Lift.lift
diff --git a/Data/Ascii.hs b/Data/Ascii.hs
deleted file mode 100644
--- a/Data/Ascii.hs
+++ /dev/null
@@ -1,61 +0,0 @@
-module Data.Ascii
-    ( -- * Datatypes
-      Ascii
-    , CIAscii
-    , AsciiBuilder
-      -- * Construction
-      -- ** Safe
-    , fromByteString
-    , fromChars
-    , fromText
-      -- ** Unsafe
-    , unsafeFromByteString
-    , unsafeFromString
-    , unsafeFromText
-      -- * Extraction
-    , toByteString
-    , toString
-    , toText
-      -- * Case insensitive
-    , toCIAscii
-    , fromCIAscii
-    , ciToByteString
-      -- * Builder
-    , toAsciiBuilder
-    , fromAsciiBuilder
-    , unsafeFromBuilder
-    , toBuilder
-      -- * Character-level functions and predicates
-    , fromChar
-    , toChar
-    , ascii
-    , isAscii
-    , isControl
-    , isPrintable
-    , isWhiteSpace
-    , isSpaceOrTab
-    , isLower
-    , isUpper
-    , toLower
-    , toUpper
-    , isAlpha
-    , isDigit
-    , isAlphaNum
-    , fromDigit
-    , unsafeFromDigit
-    , fromOctDigit
-    , unsafeFromOctDigit
-    , isUpHexDigit
-    , fromUpHexDigit
-    , unsafeFromUpHexDigit
-    , isLowHexDigit
-    , fromLowHexDigit
-    , unsafeFromLowHexDigit
-    , isHexDigit
-    , fromHexDigit
-    , unsafeFromHexDigit
-    ) where
-
-import Data.Ascii.Blaze
-import Data.Ascii.ByteString
-import Data.Ascii.Word8
diff --git a/Data/Ascii/Blaze.hs b/Data/Ascii/Blaze.hs
deleted file mode 100644
--- a/Data/Ascii/Blaze.hs
+++ /dev/null
@@ -1,27 +0,0 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-
-module Data.Ascii.Blaze where
-
-import Data.Ascii.ByteString
-
--- base
-import Data.Monoid (Monoid)
-import Data.Semigroup (Semigroup)
-
--- blaze-builder
-import qualified Blaze.ByteString.Builder as Blaze
-
-newtype AsciiBuilder = AsciiBuilder (Blaze.Builder)
-    deriving (Semigroup, Monoid)
-
-unsafeFromBuilder :: Blaze.Builder -> AsciiBuilder
-unsafeFromBuilder = AsciiBuilder
-
-toBuilder :: AsciiBuilder -> Blaze.Builder
-toBuilder (AsciiBuilder b) = b
-
-toAsciiBuilder :: Ascii -> AsciiBuilder
-toAsciiBuilder (Ascii bs) = AsciiBuilder $ Blaze.fromByteString bs
-
-fromAsciiBuilder :: AsciiBuilder -> Ascii
-fromAsciiBuilder (AsciiBuilder b) = Ascii $ Blaze.toByteString b
diff --git a/Data/Ascii/ByteString.hs b/Data/Ascii/ByteString.hs
deleted file mode 100644
--- a/Data/Ascii/ByteString.hs
+++ /dev/null
@@ -1,75 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
-
-module Data.Ascii.ByteString where
-
--- base
-import Data.Data (Data)
-import Data.Typeable (Typeable)
-import Data.String (IsString (..))
-import qualified Data.Char as C
-import Data.Monoid (Monoid)
-import Data.Semigroup (Semigroup)
-
--- bytestring
-import qualified Data.ByteString as S
-import qualified Data.ByteString.Char8 as S8
-import Data.ByteString (ByteString)
-
--- case-insensitive
-import Data.CaseInsensitive (FoldCase, CI, mk, original)
-
--- hashable
-import Data.Hashable (Hashable)
-
--- text
-import Data.Text (Text)
-import qualified Data.Text as T
-import qualified Data.Text.Encoding as TE
-
-newtype Ascii = Ascii ByteString
-    deriving (Show, Eq, Read, Ord, Data, Typeable, IsString, FoldCase, Hashable, Semigroup, Monoid)
-
-type CIAscii = CI Ascii
-
-fromByteString :: ByteString -> Maybe Ascii
-fromByteString bs
-    | S.all (< 128) bs = Just $ Ascii bs
-    | otherwise = Nothing
-
--- | Renamed to avoid clash with 'fromString'
-fromChars :: String -> Maybe Ascii
-fromChars s
-    | all C.isAscii s = Just $ Ascii $ S8.pack s
-    | otherwise = Nothing
-
-fromText :: Text -> Maybe Ascii
-fromText t
-    | T.all C.isAscii t = Just $ Ascii $ TE.encodeUtf8 t
-    | otherwise = Nothing
-
-unsafeFromByteString :: ByteString -> Ascii
-unsafeFromByteString = Ascii
-
-unsafeFromString :: String -> Ascii
-unsafeFromString = Ascii . S8.pack
-
-unsafeFromText :: Text -> Ascii
-unsafeFromText = Ascii . TE.encodeUtf8
-
-toCIAscii :: Ascii -> CIAscii
-toCIAscii = mk
-
-fromCIAscii :: CIAscii -> Ascii
-fromCIAscii = original
-
-toByteString :: Ascii -> ByteString
-toByteString (Ascii bs) = bs
-
-toString :: Ascii -> String
-toString (Ascii bs) = S8.unpack bs
-
-toText :: Ascii -> Text
-toText (Ascii bs) = TE.decodeUtf8 bs
-
-ciToByteString :: CIAscii -> ByteString
-ciToByteString = toByteString . original
diff --git a/Data/Ascii/Word8.hs b/Data/Ascii/Word8.hs
deleted file mode 100644
--- a/Data/Ascii/Word8.hs
+++ /dev/null
@@ -1,148 +0,0 @@
-{-# LANGUAGE CPP #-}
-
-module Data.Ascii.Word8 where
-
--- base
-import Data.Word (Word8)
-import qualified Data.Char as C
-
-fromChar :: Char -> Maybe Word8
-fromChar c = if i < 128 then Just (fromIntegral i) else Nothing
-  where i = C.ord c
-
-toChar :: Word8 -> Char
-toChar = C.chr . fromIntegral
-
--- | Unsafe version of 'fromChar'
-ascii :: Char -> Word8
-ascii = fromIntegral . C.ord
-{-# INLINE ascii #-}
-
-isAscii :: Word8 -> Bool
-isAscii = (< 128)
-
-isControl :: Word8 -> Bool
-isControl w = w < 32 || w == 127
-
-isPrintable :: Word8 -> Bool
-isPrintable w = w >= 32 && w < 127
-
-isWhiteSpace :: Word8 -> Bool
-isWhiteSpace w = w == ascii ' ' || w >= 9 && w <= 13
-
-isSpaceOrTab :: Word8 -> Bool
-isSpaceOrTab w = w == ascii ' ' || w == ascii '\t'
-
-isLower :: Word8 -> Bool
-isLower w = w >= ascii 'a' && w <= ascii 'z'
-
-isUpper :: Word8 -> Bool
-isUpper w = w >= ascii 'A' && w <= ascii 'Z'
-
-toLower :: Word8 -> Word8
-toLower w | isUpper w = w + 32
-          | otherwise = w
-
-toUpper :: Word8 -> Word8
-toUpper w | isLower w = w - 32
-          | otherwise = w
-
-isAlpha :: Word8 -> Bool
-isAlpha w = isUpper w || isLower w
-
-isDigit :: Word8 -> Bool
-isDigit w = w >= ascii '0' && w <= ascii '9'
-
-isAlphaNum :: Word8 -> Bool
-isAlphaNum w = isDigit w || isAlpha w
-
-fromDigit :: Num a => Word8 -> Maybe a
-fromDigit w | isDigit w = Just $ unsafeFromDigit w
-            | otherwise = Nothing
-#if __GLASGOW_HASKELL__ >= 700
-{-# INLINABLE fromDigit #-}
-#endif
-
-unsafeFromDigit :: Num a => Word8 -> a
-unsafeFromDigit w = fromIntegral (w - ascii '0')
-{-# INLINE unsafeFromDigit #-}
-
-isOctDigit :: Word8 -> Bool
-isOctDigit w = w >= ascii '0' && w <= ascii '7'
-
-fromOctDigit :: Num a => Word8 -> Maybe a
-fromOctDigit w | isOctDigit w = Just $ unsafeFromOctDigit w
-               | otherwise    = Nothing
-#if __GLASGOW_HASKELL__ >= 700
-{-# INLINABLE fromOctDigit #-}
-#endif
-
-unsafeFromOctDigit :: Num a => Word8 -> a
-unsafeFromOctDigit = unsafeFromDigit
-{-# INLINE unsafeFromOctDigit #-}
-
-isLowAF :: Word8 -> Bool
-isLowAF w = w >= ascii 'a' && w <= ascii 'f'
-{-# INLINE isLowAF #-}
-
-fromLowAF :: Num a => Word8 -> a
-fromLowAF w = fromIntegral (w - ascii 'a' + 10)
-{-# INLINE fromLowAF #-}
-
-isLowHexDigit :: Word8 -> Bool
-isLowHexDigit w = isDigit w || isLowAF w
-
-fromLowHexDigit :: Num a => Word8 -> Maybe a
-fromLowHexDigit w | isDigit w = Just $ unsafeFromDigit w
-                  | isLowAF w = Just $ fromLowAF w
-                  | otherwise = Nothing
-#if __GLASGOW_HASKELL__ >= 700
-{-# INLINABLE fromLowHexDigit #-}
-#endif
-
-unsafeFromLowHexDigit :: Num a => Word8 -> a
-unsafeFromLowHexDigit w | w < ascii 'a' = unsafeFromDigit w
-                        | otherwise     = fromLowAF w
-{-# INLINE unsafeFromLowHexDigit #-}
-
-isUpAF :: Word8 -> Bool
-isUpAF w = w >= ascii 'A' && w <= ascii 'F'
-{-# INLINE isUpAF #-}
-
-fromUpAF :: Num a => Word8 -> a
-fromUpAF w = fromIntegral (w - ascii 'A' + 10)
-{-# INLINE fromUpAF #-}
-
-isUpHexDigit :: Word8 -> Bool
-isUpHexDigit w = isDigit w || isUpAF w
-
-fromUpHexDigit :: Num a => Word8 -> Maybe a
-fromUpHexDigit w | isDigit w = Just $ unsafeFromDigit w
-                 | isUpAF w  = Just $ fromUpAF w
-                 | otherwise = Nothing
-#if __GLASGOW_HASKELL__ >= 700
-{-# INLINABLE fromUpHexDigit #-}
-#endif
-
-unsafeFromUpHexDigit :: Num a => Word8 -> a
-unsafeFromUpHexDigit w | w < ascii 'A' = unsafeFromDigit w
-                       | otherwise     = fromUpAF w
-{-# INLINE unsafeFromUpHexDigit #-}
-
-isHexDigit :: Word8 -> Bool
-isHexDigit w = isDigit w || isUpAF w || isLowAF w
-
-fromHexDigit :: Num a => Word8 -> Maybe a
-fromHexDigit w | isDigit w = Just $ unsafeFromDigit w
-               | isUpAF w  = Just $ fromUpAF w
-               | isLowAF w = Just $ fromLowAF w
-               | otherwise = Nothing
-#if __GLASGOW_HASKELL__ >= 700
-{-# INLINABLE fromHexDigit #-}
-#endif
-
-unsafeFromHexDigit :: Num a => Word8 -> a
-unsafeFromHexDigit w | w < ascii 'A' = unsafeFromDigit w
-                     | w < ascii 'a' = fromUpAF w
-                     | otherwise     = fromLowAF w
-{-# INLINE unsafeFromHexDigit #-}
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
--- a/LICENSE
+++ /dev/null
@@ -1,30 +0,0 @@
-Copyright Michael Snoyman 2011, Typeclass Consulting LLC 2018
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-
-    * Neither the name of Michael Snoyman nor the names of other
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env runhaskell
-import Distribution.Simple
-main = defaultMain
diff --git a/ascii.cabal b/ascii.cabal
--- a/ascii.cabal
+++ b/ascii.cabal
@@ -1,40 +1,66 @@
-Name:                ascii
-Version:             0.0.5.2
-Synopsis:            Type-safe, bytestring-based ASCII values
-Description:         Type-safe, bytestring-based ASCII values.
-License:             BSD3
-License-file:        LICENSE
-Author:              Michael Snoyman
-Maintainer:          Chris Martin, Julie Moronuki
-Stability:           Stable
-Category:            Data
-Homepage:            https://github.com/typeclasses/ascii
-Bug-Reports:         https://github.com/typeclasses/ascii/issues
-Build-type:          Simple
-Cabal-version:       >= 1.6
-Tested-with:         GHC == 8.4.3
-                   , GHC == 8.2.2
-                   , GHC == 7.10.3
-                   , GHC == 7.8.4
-                   , GHC == 7.6.3
-                   , GHC == 7.4.2
-                   , GHC == 7.2.2
-                   , GHC == 7.0.4
+cabal-version: 2.0
 
-Source-Repository head
-    Type:     git
-    Location: git://github.com/typeclasses/ascii.git
+name: ascii
+version: 1.0.0.0
+synopsis: The ASCII character set and encoding
+category: Data, Text
 
-Library
-  Exposed-modules:     Data.Ascii
-                     , Data.Ascii.Blaze
-                     , Data.Ascii.ByteString
-                     , Data.Ascii.Word8
-  Build-depends:       base             >= 4             && < 5
-                     , bytestring       >= 0.9           && < 0.11
-                     , text             >= 0.11          && < 1.3
-                     , blaze-builder    >= 0.2.1.4       && < 0.5
-                     , case-insensitive >= 0.2           && < 1.3
-                     , hashable         >= 1.0           && < 1.3
-                     , semigroups
-  Ghc-options:         -Wall
+description: This package provides a variety of ways to work with ASCII text.
+
+license: Apache-2.0
+license-file: license.txt
+
+author: Chris Martin
+maintainer: Chris Martin, Julie Moronuki
+
+homepage:    https://github.com/typeclasses/ascii
+bug-Reports: https://github.com/typeclasses/ascii/issues
+
+build-type: Simple
+
+tested-with: GHC == 8.8.1, GHC == 8.6.5, GHC == 8.4.3
+
+source-repository head
+    type:     git
+    location: git://github.com/typeclasses/ascii.git
+
+library
+    default-language: Haskell2010
+    default-extensions: NoImplicitPrelude
+    ghc-options: -Wall
+
+    build-depends: base       >= 4.11 && < 4.14
+    build-depends: bytestring >= 0.10 && < 0.11
+    build-depends: text       >= 1.2  && < 1.3
+
+    exposed-modules: ASCII
+
+    build-depends: ascii-char >= 1.0 && < 1.1
+    reexported-modules: ASCII.Char
+
+    build-depends: ascii-group >= 1.0 && < 1.1
+    reexported-modules: ASCII.Group
+
+    build-depends: ascii-case >= 1.0 && < 1.1
+    reexported-modules: ASCII.Case
+
+    build-depends: ascii-predicates >= 1.0 && < 1.1
+    reexported-modules: ASCII.Predicates
+    reexported-modules: ASCII.Lists
+    reexported-modules: ASCII.ListsAndPredicates
+
+    build-depends: ascii-superset >= 1.0 && < 1.1
+    reexported-modules: ASCII.Superset
+    reexported-modules: ASCII.Isomorphism
+    reexported-modules: ASCII.Refinement
+    reexported-modules: ASCII.Lift
+
+    build-depends: ascii-th >= 1.0 && < 1.1
+    reexported-modules: ASCII.TemplateHaskell
+    reexported-modules: ASCII.QuasiQuoters
+
+    build-depends: data-ascii >= 1.0 && < 1.1
+    reexported-modules: Data.Ascii
+    reexported-modules: Data.Ascii.Blaze
+    reexported-modules: Data.Ascii.ByteString
+    reexported-modules: Data.Ascii.Word8
diff --git a/license.txt b/license.txt
new file mode 100644
--- /dev/null
+++ b/license.txt
@@ -0,0 +1,13 @@
+Copyright 2020 Typeclass Consulting LLC
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
