diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,14 @@
+Text-Latin1
+===========
+
+[![Travis](https://img.shields.io/travis/mvv/text-latin1/master.svg)](https://travis-ci.org/mvv/text-latin1) [![Hackage](https://img.shields.io/hackage/v/text-latin1.svg)](http://hackage.haskell.org/package/text-latin1)
+
+This package provides various functions over the ASCII and Latin-1 portions of
+the `Char` and `Word8` data types.
+
+Installation
+------------
+The usual:
+
+	$ cabal install
+
diff --git a/src/Text/Ascii.hs b/src/Text/Ascii.hs
--- a/src/Text/Ascii.hs
+++ b/src/Text/Ascii.hs
@@ -107,6 +107,7 @@
 import qualified Data.ByteString.Lazy as BL
 import qualified Data.Text as TS
 import qualified Data.Text.Lazy as TL
+import Data.Semigroup (Semigroup(..))
 import Data.Monoid (Monoid(..))
 import Data.CaseInsensitive (FoldCase(..))
 import Data.Hashable (Hashable(..))
@@ -158,11 +159,21 @@
 instance Show α ⇒ Show (Ascii α) where
   showsPrec p = showsPrec p . checked
 
+instance Semigroup α ⇒ Semigroup (Ascii α) where
+  x <> y = trustMe $ checked x <> checked y
+  {-# INLINE (<>) #-}
+  sconcat = trustMe . sconcat . fmap checked
+  {-# INLINE sconcat #-}
+  stimes n = trustMe . stimes n . checked
+  {-# INLINE stimes #-}
+
 instance Monoid α ⇒ Monoid (Ascii α) where
   mempty = trustMe mempty
   {-# INLINE mempty #-}
   mappend x y = trustMe $ mappend (checked x) (checked y)
   {-# INLINE mappend #-}
+  mconcat = trustMe . mconcat . fmap checked
+  {-# INLINE mconcat #-}
 
 instance IsString α ⇒ IsString (Ascii α) where
   fromString s | isAscii s = trustMe $ fromString s
diff --git a/src/Text/Latin1.hs b/src/Text/Latin1.hs
--- a/src/Text/Latin1.hs
+++ b/src/Text/Latin1.hs
@@ -47,6 +47,7 @@
 import qualified Data.Text.Lazy as TL
 import Text.Ascii (Ascii)
 import qualified Text.Ascii as A
+import Data.Semigroup (Semigroup(..))
 import Data.Monoid (Monoid(..))
 import Data.CaseInsensitive (FoldCase(..))
 import Data.Hashable (Hashable(..))
@@ -86,11 +87,21 @@
 instance Show α ⇒ Show (Latin1 α) where
   showsPrec p = showsPrec p . checked
 
+instance Semigroup α ⇒ Semigroup (Latin1 α) where
+  x <> y = trustMe $ checked x <> checked y
+  {-# INLINE (<>) #-}
+  sconcat = trustMe . sconcat . fmap checked
+  {-# INLINE sconcat #-}
+  stimes n = trustMe . stimes n . checked
+  {-# INLINE stimes #-}
+
 instance Monoid α ⇒ Monoid (Latin1 α) where
   mempty = trustMe mempty
   {-# INLINE mempty #-}
   mappend x y = trustMe $ mappend (checked x) (checked y)
   {-# INLINE mappend #-}
+  mconcat = trustMe . mconcat . fmap checked
+  {-# INLINE mconcat #-}
 
 instance IsString α ⇒ IsString (Latin1 α) where
   fromString s | isLatin1 s = trustMe $ fromString s
diff --git a/text-latin1.cabal b/text-latin1.cabal
--- a/text-latin1.cabal
+++ b/text-latin1.cabal
@@ -1,5 +1,5 @@
 Name: text-latin1
-Version: 0.3
+Version: 0.3.1
 Category: Text
 Stability: experimental
 Synopsis: Latin-1 (including ASCII) utility functions
@@ -16,6 +16,12 @@
 License: BSD3
 License-File: LICENSE
 
+Extra-Source-Files:
+  README.md
+
+Tested-With: GHC==7.0.4, GHC==7.2.2, GHC==7.4.2, GHC==7.6.3, GHC==7.8.4,
+             GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.1
+
 Cabal-Version: >= 1.6.0
 Build-Type: Simple
 
@@ -28,6 +34,7 @@
                , data-checked >= 0.2
                , bytestring
                , text
+               , semigroups >= 0.18.4
                , case-insensitive >= 1.0
                , hashable >= 1.1
   Hs-Source-Dirs: src
@@ -35,4 +42,3 @@
   Exposed-Modules:
     Text.Ascii
     Text.Latin1
-
