diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
--- a/.travis.yml
+++ /dev/null
@@ -1,1 +0,0 @@
-language: haskell
diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.markdown
@@ -0,0 +1,28 @@
+0.3.8 [2021.02.17]
+------------------
+* Add an `IsString CharSet` instance.
+
+0.3.7.1
+-------
+* Minor haddock fixup.
+
+0.3.7
+-----
+* Switched to derived Typeable for GHC 7.8 compatibility
+
+0.3.6
+-----
+* Removed some duplicated blocks in `Data.CharSet.Unicode.Block.blocks`, see issue #3.
+
+0.3.5.1
+-------
+* Updated dependencies to support GHC 7.8
+
+0.3.5
+-----
+* Claim to be Trustworthy.
+
+0.3.3
+-----
+* Removed upper bounds on my other packages
+
diff --git a/README.markdown b/README.markdown
new file mode 100644
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,15 @@
+charsets
+========
+
+[![Hackage](https://img.shields.io/hackage/v/charset.svg)](https://hackage.haskell.org/package/charset) [![Build Status](https://github.com/ekmett/charset/workflows/Haskell-CI/badge.svg)](https://github.com/ekmett/charset/actions?query=workflow%3AHaskell-CI)
+
+Fast utf-8 character sets for Haskell represented as complemented PATRICIA tries.
+
+Contact Information
+-------------------
+
+Contributions and bug reports are welcome!
+
+Please feel free to contact me through github or on the #haskell IRC channel on irc.freenode.net.
+
+-Edward Kmett
diff --git a/charset.cabal b/charset.cabal
--- a/charset.cabal
+++ b/charset.cabal
@@ -1,35 +1,50 @@
 name:          charset
-version:       0.3.7.1
+version:       0.3.8
 license:       BSD3
 license-File:  LICENSE
 copyright:     (c) Edward Kmett 2010-2012
 author:        Edward Kmett
 maintainer:    ekmett@gmail.com
-cabal-version: >= 1.6
+cabal-version: >= 1.10
 stability:     Experimental
 category:      Data
 homepage:      http://github.com/ekmett/charset
 bug-reports:   http://github.com/ekmett/charset/issues
 synopsis:      Fast unicode character sets based on complemented PATRICIA tries
-description:   Fast unicode character sets based on complemented PATRICIA tries
+description:   Fast unicode character sets based on complemented PATRICIA tries.
 build-type:    Simple
-extra-source-files: .travis.yml
+extra-source-files: CHANGELOG.markdown, README.markdown
 
+tested-with:
+  GHC ==7.0.4
+   || ==7.2.2
+   || ==7.4.2
+   || ==7.6.3
+   || ==7.8.4
+   || ==7.10.3
+   || ==8.0.2
+   || ==8.2.2
+   || ==8.4.4
+   || ==8.6.5
+   || ==8.8.3
+   || ==8.10.1
+
 source-repository head
   type: git
   location: git://github.com/ekmett/charset.git
 
 library
-  extensions: CPP
+  default-extensions: CPP
   other-extensions: MagicHash, BangPatterns
 
   build-depends:
     base                 >= 4       && < 5,
     array                >= 0.2     && < 0.6,
-    bytestring           >= 0.9     && < 0.11,
-    containers           >= 0.2     && < 0.6,
-    semigroups           >= 0.8.3.1 && < 1,
+    bytestring           >= 0.9     && < 0.12,
+    containers           >= 0.2     && < 0.7,
     unordered-containers >= 0.1.4.6 && < 0.3
+  if impl(ghc < 8.0)
+    build-depends: semigroups >= 0.8.3.1 && < 1
 
   exposed-modules:
     Data.CharSet
@@ -44,3 +59,4 @@
 
   hs-source-dirs: src
   ghc-options: -Wall -fspec-constr -fdicts-cheap -O2
+  default-language: Haskell2010
diff --git a/src/Data/CharSet.hs b/src/Data/CharSet.hs
--- a/src/Data/CharSet.hs
+++ b/src/Data/CharSet.hs
@@ -13,12 +13,12 @@
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- Fast set membership tests for 'Char' values
---
--- Stored as a (possibly negated) IntMap and a fast set used for the head byte.
+-- A CharSet is an /efficient/ representation of a set of 'Char' values
+-- designed for fast membership tests.
 --
--- The set of valid (possibly negated) head bytes is stored unboxed as a 32-byte
--- bytestring-based lookup table.
+-- As an example @build isAlpha@ will create a set of alphabetic characters.
+-- We can then use 'member' on the generated set to /efficiently/ test if a
+-- given @Char@ represents an alphabetic character.
 --
 -- Designed to be imported qualified:
 --
@@ -75,6 +75,11 @@
     , toArray
     ) where
 
+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 608
+import Data.String (IsString(..))
+-- <<< -XOverloadedStrings >>> was introduced by GHC 6.8.1
+#endif
+
 import Data.Array.Unboxed hiding (range)
 import Data.Data
 import Data.Function (on)
@@ -91,9 +96,22 @@
 import qualified Prelude as P
 import Text.Read
 
-data CharSet = CharSet !Bool {-# UNPACK #-} !ByteSet !IntSet
+-- | Stored as a (possibly negated) IntSet and a fast set used for the head byte.
+--
+-- The set of valid (possibly negated) head bytes is stored unboxed as a 32-byte
+-- bytestring-based lookup table.
+data CharSet = CharSet
+    !Bool    -- Whether ByteSet and IntSet are negated
+    !ByteSet -- Set of head bytes, unboxed
+    !IntSet  -- Set of characters in the charset
   deriving Typeable
 
+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 608
+-- | @= CharSet.`fromList`@
+instance IsString CharSet where
+  fromString = fromList
+#endif
+
 charSet :: Bool -> IntSet -> CharSet
 charSet b s = CharSet b (ByteSet.fromList (fmap headByte (I.toAscList s))) s
 
@@ -113,6 +131,11 @@
 (\\) :: CharSet -> CharSet -> CharSet
 (\\) = difference
 
+-- | Applies a predicate across the whole range of possible character values
+-- to create a set of only those characters which satisfy the predicate.
+--
+-- As an example @build isAlpha@ will generate a CharSet of all
+-- alphabetic characters.
 build :: (Char -> Bool) -> CharSet
 build p = fromDistinctAscList $ P.filter p [minBound .. maxBound]
 {-# INLINE build #-}
diff --git a/src/Data/CharSet/ByteSet.hs b/src/Data/CharSet/ByteSet.hs
--- a/src/Data/CharSet/ByteSet.hs
+++ b/src/Data/CharSet/ByteSet.hs
@@ -14,9 +14,11 @@
 -- Stability   :  experimental
 -- Portability :  non-portable (BangPatterns, MagicHash)
 --
--- Fast set membership tests for byte values, The set representation is
--- unboxed for efficiency and uses a lookup table. This is a fairly minimal
--- API. You probably want to use CharSet.
+-- Fast set membership tests for byte values. The set representation is
+-- unboxed for efficiency and uses one bit per byte to represent the presence
+-- or absence of a byte in the set.
+--
+-- This is a fairly minimal API. You probably want to use CharSet.
 -----------------------------------------------------------------------------
 module Data.CharSet.ByteSet
     (
@@ -38,7 +40,11 @@
 
 newtype ByteSet = ByteSet B.ByteString deriving (Eq, Ord, Show)
 
-data I = I {-# UNPACK #-} !Int {-# UNPACK #-} !Word8
+-- | Representation of the index of a bit inside a bytestring
+-- in terms of a byte index and a bit index inside the byte
+data I = I
+    {-# UNPACK #-} !Int         -- byte index
+    {-# UNPACK #-} !Word8       -- bit index
 
 shiftR :: Int -> Int -> Int
 shiftR (I# x#) (I# i#) = I# (x# `iShiftRA#` i#)
@@ -46,6 +52,7 @@
 shiftL :: Word8 -> Int -> Word8
 shiftL (W8# x#) (I# i#) = W8# (narrow8Word# (x# `shiftL#` i#))
 
+-- | Convert a bit index to a byte index and bit index inside the byte
 index :: Int -> I
 index i = I (i `shiftR` 3) (1 `shiftL` (i .&. 7))
 {-# INLINE index #-}
