diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,7 @@
 Changelog for TagSoup
 
+0.14.8, released 2019-05-01
+    #78, add strMap
 0.14.7, released 2018-09-18
     #75, escape single quote (') characters as &#39;
     #72, update some dead URLs
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright Neil Mitchell 2006-2018.
+Copyright Neil Mitchell 2006-2019.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# TagSoup [![Hackage version](https://img.shields.io/hackage/v/tagsoup.svg?label=Hackage)](https://hackage.haskell.org/package/tagsoup) [![Stackage version](https://www.stackage.org/package/tagsoup/badge/nightly?label=Stackage)](https://www.stackage.org/package/tagsoup) [![Linux Build Status](https://img.shields.io/travis/ndmitchell/tagsoup/master.svg?label=Linux%20build)](https://travis-ci.org/ndmitchell/tagsoup) [![Windows Build Status](https://img.shields.io/appveyor/ci/ndmitchell/tagsoup/master.svg?label=Windows%20build)](https://ci.appveyor.com/project/ndmitchell/tagsoup)
+# TagSoup [![Hackage version](https://img.shields.io/hackage/v/tagsoup.svg?label=Hackage)](https://hackage.haskell.org/package/tagsoup) [![Stackage version](https://www.stackage.org/package/tagsoup/badge/nightly?label=Stackage)](https://www.stackage.org/package/tagsoup) [![Linux build status](https://img.shields.io/travis/ndmitchell/tagsoup/master.svg?label=Linux%20build)](https://travis-ci.org/ndmitchell/tagsoup) [![Windows build status](https://img.shields.io/appveyor/ci/ndmitchell/tagsoup/master.svg?label=Windows%20build)](https://ci.appveyor.com/project/ndmitchell/tagsoup)
 
 TagSoup is a library for parsing HTML/XML. It supports the HTML 5 specification, and can be used to parse either well-formed XML, or unstructured and malformed HTML from the web. The library also provides useful functions to extract information from an HTML document, making it ideal for screen-scraping.
 
@@ -74,16 +74,6 @@
 
 Now open `temp.htm`, find the fragment of HTML containing the hit count, and examine it.
 
-#### Using the `tagsoup` Program
-
-TagSoup installs both as a library and a program. The program contains all the
-examples mentioned on this page, along with a few other useful functions. In
-order to download a URL to a file:
-
-```bash
-$ tagsoup grab http://wiki.haskell.org/Haskell > temp.htm
-```
-
 ### Finding the Information
 
 Now we examine both the fragment that contains our snippet of information, and
@@ -204,7 +194,7 @@
 
 ## Other Examples
 
-Several more examples are given in the Example file, including obtaining the (short) list of papers from my site, getting the current time and a basic XML validator. All can be invoked using the `tagsoup` executable program. All use very much the same style as presented here - writing screen scrapers follow a standard pattern. We present the code from two for enjoyment only.
+Several more examples are given in the [Sample.hs](https://github.com/ndmitchell/tagsoup/blob/master/test/TagSoup/Sample.hs) file, including obtaining the (short) list of papers from my site, getting the current time and a basic XML validator. All use very much the same style as presented here - writing screen scrapers follow a standard pattern. We present the code from two for enjoyment only.
 
 ### My Papers
 
@@ -252,6 +242,7 @@
 ```
 
 ## Other Examples
+
 In [Sample.hs](https://github.com/ndmitchell/tagsoup/blob/master/test/TagSoup/Sample.hs)
 the following additional examples are listed:
 
@@ -259,7 +250,6 @@
 - Package list form Hackage
 - Print names of story contributors on sequence.complete.org
 - Parse rows of a table
-
 
 ## Related Projects
 
diff --git a/src/Text/StringLike.hs b/src/Text/StringLike.hs
--- a/src/Text/StringLike.hs
+++ b/src/Text/StringLike.hs
@@ -37,6 +37,8 @@
     strNull :: a -> Bool
     -- | > append = (++)
     append :: a -> a -> a
+    -- | > strMap = map
+    strMap :: (Char -> Char) -> a -> a
 
 
 -- | Convert a String from one type to another.
@@ -54,6 +56,7 @@
     strNull = null
     cons c = (c:)
     append = (++)
+    strMap = fmap
 
 instance StringLike BS.ByteString where
     uncons = BS.uncons
@@ -64,6 +67,7 @@
     strNull = BS.null
     cons = BS.cons
     append = BS.append
+    strMap = BS.map
 
 instance StringLike LBS.ByteString where
     uncons = LBS.uncons
@@ -74,6 +78,7 @@
     strNull = LBS.null
     cons = LBS.cons
     append = LBS.append
+    strMap = LBS.map
 
 instance StringLike T.Text where
     uncons = T.uncons
@@ -84,6 +89,7 @@
     strNull = T.null
     cons = T.cons
     append = T.append
+    strMap = T.map
 
 instance StringLike LT.Text where
     uncons = LT.uncons
@@ -94,3 +100,4 @@
     strNull = LT.null
     cons = LT.cons
     append = LT.append
+    strMap = LT.map
diff --git a/tagsoup.cabal b/tagsoup.cabal
--- a/tagsoup.cabal
+++ b/tagsoup.cabal
@@ -1,7 +1,7 @@
 cabal-version:  >= 1.18
 name:           tagsoup
-version:        0.14.7
-copyright:      Neil Mitchell 2006-2018
+version:        0.14.8
+copyright:      Neil Mitchell 2006-2019
 author:         Neil Mitchell <ndmitchell@gmail.com>
 maintainer:     Neil Mitchell <ndmitchell@gmail.com>
 homepage:       https://github.com/ndmitchell/tagsoup#readme
@@ -11,7 +11,7 @@
 license-file:   LICENSE
 build-type:     Simple
 synopsis:       Parsing and extracting information from (possibly malformed) HTML/XML documents
-tested-with:    GHC==8.4.3, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2
+tested-with:    GHC==8.6.5, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3
 description:
     TagSoup is a library for parsing HTML/XML. It supports the HTML 5 specification,
     and can be used to parse either well-formed XML, or unstructured and malformed HTML
diff --git a/test/TagSoup/Benchmark.hs b/test/TagSoup/Benchmark.hs
--- a/test/TagSoup/Benchmark.hs
+++ b/test/TagSoup/Benchmark.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-} -- test file, so OK
 
 module TagSoup.Benchmark where
@@ -67,7 +66,7 @@
 
 disp xs = showUnit (floor xbar) ++ " (~" ++ rng ++ "%)"
     where xbar = mean xs
-          rng = if length xs <= 1 then "?" else show (ceiling $ (range conf xs) * 100 / xbar) 
+          rng = if length xs <= 1 then "?" else show (ceiling $ (range conf xs) * 100 / xbar)
 
 cons x = fmap (x:)
 
@@ -157,23 +156,6 @@
     rnf (TagComment x) = rnf x
     rnf (TagWarning x) = rnf x
     rnf (TagPosition x y) = () -- both are already ! bound
-
-
-#ifndef BYTESTRING_HAS_NFDATA
-# ifdef MIN_VERSION_bytestring
-#  define BYTESTRING_HAS_NFDATA (MIN_VERSION_bytestring(0,10,0))
-# else
-#  define BYTESTRING_HAS_NFDATA (__GLASGOW_HASKELL__ >= 706)
-# endif
-#endif
-
-#if !BYTESTRING_HAS_NFDATA
-instance NFData LBS.ByteString where
-    rnf x = LBS.length x `seq` ()
-
-instance NFData BS.ByteString where
-    rnf x = BS.length x `seq` ()
-#endif
 
 
 ---------------------------------------------------------------------
