diff --git a/ListLike.cabal b/ListLike.cabal
--- a/ListLike.cabal
+++ b/ListLike.cabal
@@ -1,5 +1,5 @@
 Name: ListLike
-Version: 3.0.1
+Version: 3.1.0
 License: BSD3
 Maintainer: John Lato <jwlato@gmail.com>
 Author: John Goerzen
@@ -24,6 +24,7 @@
 Hs-Source-Dirs: src
 Exposed-Modules: Data.ListLike,
         Data.ListLike.Base,
+        Data.ListLike.CharString,
         Data.ListLike.FoldableLL,
         Data.ListLike.IO,
         Data.ListLike.Instances,
diff --git a/src/Data/ListLike.hs b/src/Data/ListLike.hs
--- a/src/Data/ListLike.hs
+++ b/src/Data/ListLike.hs
@@ -93,12 +93,11 @@
                  -- ** Arrays
                  -- $notesarray
 
-                 -- ** Maps
-                 -- $notesmap
-
                  -- ** ByteStrings
                  -- $notesbytestring
-                 
+                 CharString (..),
+                 CharStringLazy (..),
+
                  -- * Base Typeclasses
                  -- ** The ListLike class
                  ListLike,
@@ -119,6 +118,7 @@
                        splitAt, elem, notElem, unzip, lines, words,
                        unlines, unwords)
 import Data.ListLike.Base
+import Data.ListLike.CharString
 import Data.ListLike.FoldableLL
 import Data.ListLike.Instances()
 import Data.ListLike.String
@@ -205,37 +205,14 @@
   not assigned a value to every slot in the array.
 -}
 
-{- $notesmap
-
-'Data.Map.Map' is an instance of 'ListLike' and is a rather interesting one at
-that.  The \"item\" for the Map instance is a @(key, value)@ pair.  This
-permits you to do folds, maps, etc. over a Map just like you would on a list.
-
-The nature of a Map -- that every key is unique, and that it is internally
-sorted -- means that there are some special things to take note of:
-
-* 'cons' may or may not actually increase the size of the Map.  If the given
-   key is already in the map, its value will simply be updated.  Since
-   a Map has a set internal ordering, it is also not guaranteed that cons
-   will add something to the beginning of the Map.
-
-* 'snoc' is the same operation as 'cons'.
-
-* 'append' is 'Data.Map.union'
-
-* 'nub', 'nubBy',
-  'reverse', 'sort', 'sortBy', etc. are the identity function and don\'t
-  actually perform any computation
-
-* 'insert' is the same as 'cons'.
-
-* 'replicate' and 'genericReplicate' ignore the count and return a Map
-  with a single element.
--}
-
 {- $notesbytestring
 
 Both strict and lazy ByteStreams can be used with 'ListLike'.
+
+ByteString ListLike instances operate on 'Word8' elements.  This is because
+both Data.ByteString.ByteString and Data.ByteString.Char8.ByteString have
+the same underlying type.  If you wish to use the Char8 representation,
+the newtype wrappers 'CharString' and 'CharStringLazy' are available.
 
 Most 'ListLike' operations map directly to ByteStream options.  Notable
 exceptions:
diff --git a/src/Data/ListLike/CharString.hs b/src/Data/ListLike/CharString.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/ListLike/CharString.hs
@@ -0,0 +1,293 @@
+{-# LANGUAGE MultiParamTypeClasses            
+            ,FlexibleInstances
+            ,TypeSynonymInstances #-}
+
+
+{-
+Copyright (C) 2007 John Goerzen <jgoerzen@complete.org>
+
+All rights reserved.
+
+For license and copyright information, see the file COPYRIGHT
+
+-}
+
+{- |
+   Module     : Data.ListLike.CharString
+   Copyright  : Copyright (C) 2007 John Goerzen
+   License    : BSD3
+
+   Maintainer : John Lato <jwlato@gmail.com>
+   Stability  : provisional
+   Portability: portable
+
+Newtype wrapper for ByteString to enable a Char-based interface
+Re-exported by "Data.ListLike".
+
+Written by John Lato, jwlato\@gmail.com
+-}
+
+module Data.ListLike.CharString (
+  CharString (..)
+ ,CharStringLazy (..)
+)
+
+where
+
+import Prelude hiding (length, head, last, null, tail, map, filter, concat, 
+                       any, lookup, init, all, foldl, foldr, foldl1, foldr1,
+                       maximum, minimum, iterate, span, break, takeWhile,
+                       dropWhile, reverse, zip, zipWith, sequence,
+                       sequence_, mapM, mapM_, concatMap, and, or, sum,
+                       product, repeat, replicate, cycle, take, drop,
+                       splitAt, elem, notElem, unzip, lines, words,
+                       unlines, unwords)
+import qualified Data.Foldable as F
+import           Data.ListLike.Base
+import           Data.ListLike.String
+import           Data.ListLike.IO
+import           Data.ListLike.FoldableLL
+import           Data.Int
+import           Data.Monoid
+import qualified Data.ByteString.Char8 as BS
+import qualified Data.ByteString.Lazy.Char8 as BSL
+import qualified System.IO as IO
+import           Data.Word
+import           Control.Arrow
+
+--------------------------------------------------
+-- ByteString
+
+-- | Newtype wrapper around Data.ByteString.Char8.ByteString,
+--   this allows for ListLike instances with Char elements.
+newtype CharString = CS { unCS :: BS.ByteString }
+  deriving (Read, Show, Eq, Ord)
+
+instance Monoid CharString where
+  mempty = CS mempty
+  mappend l r = CS $ mappend (unCS l) (unCS r)
+
+instance FoldableLL CharString Char where
+    foldl f i0  ls = BS.foldl f i0 (unCS ls)
+    foldl' f i0 ls = BS.foldl' f i0 (unCS ls)
+    foldl1 f    ls = BS.foldl1 f (unCS ls)
+    foldr f i0  ls = BS.foldr f i0 (unCS ls)
+    foldr1 f    ls = BS.foldr1 f (unCS ls)
+
+instance ListLike CharString Char where
+    empty = CS BS.empty
+    singleton = CS . BS.singleton
+    cons x l = CS (BS.cons x (unCS l))
+    snoc l x = CS (BS.snoc (unCS l) x)
+    append l r = CS $ BS.append (unCS l) (unCS r)
+    head = BS.head . unCS
+    last = BS.last . unCS
+    tail = CS . BS.tail . unCS
+    init = CS . BS.init . unCS
+    null = BS.null . unCS
+    length = fromIntegral . BS.length . unCS
+    -- map = BS.map
+    rigidMap f = CS . BS.map f . unCS
+    reverse = CS . BS.reverse . unCS
+    --intersperse = BS.intersperse
+    concat = CS . BS.concat . map unCS . toList
+    --concatMap = BS.concatMap
+    rigidConcatMap f = CS . BS.concatMap (unCS . f) . unCS
+    any p = BS.any p . unCS
+    all p = BS.all p . unCS
+    maximum = BS.maximum . unCS
+    minimum = BS.minimum . unCS
+    replicate i = CS . BS.replicate (fromIntegral i)
+    take i = CS . BS.take (fromIntegral i) . unCS
+    drop i = CS . BS.drop (fromIntegral i) . unCS
+    splitAt i = (CS *** CS) . BS.splitAt (fromIntegral i) . unCS
+    takeWhile p = CS . BS.takeWhile p . unCS
+    dropWhile p = CS . BS.dropWhile p . unCS
+    span p  = (CS *** CS) . BS.span p . unCS
+    break p = (CS *** CS) . BS.break p . unCS
+    group = fromList . map CS . BS.group . unCS
+    inits = fromList . map CS . BS.inits . unCS
+    tails = fromList . map CS . BS.tails . unCS
+    isPrefixOf p f = BS.isPrefixOf (unCS p) (unCS f)
+    --isSuffixOf = BS.isSuffixOf
+    --isInfixOf = BS.isInfixOf
+    elem x = BS.elem x . unCS
+    notElem x = BS.notElem x . unCS
+    find p = BS.find p . unCS
+    filter p = CS . BS.filter p . unCS
+    --partition = BS.partition
+    index l i = BS.index (unCS l) (fromIntegral i)
+    elemIndex i = BS.elemIndex i  . unCS
+    --elemIndices x = fromList . L.map fromIntegral . BS.elemIndices x
+    findIndex f = BS.findIndex f . unCS
+    --findIndices x = fromList . L.map fromIntegral . BS.findIndices x
+    --sequence = BS.sequence
+    --mapM = BS.mapM
+    --mapM_ = BS.mapM_
+    --nub = BS.nub
+    --delete = BS.delete
+    --deleteFirsts = BS.deleteFirsts
+    --union = BS.union
+    --intersect = BS.intersect
+    --sort = BS.sort
+    --insert = BS.insert
+    toList = BS.unpack . unCS
+    fromList = CS . BS.pack
+    fromListLike = fromList . toList
+    --nubBy = BS.nubBy
+    --deleteBy = BS.deleteBy
+    --deleteFirstsBy = BS.deleteFirstsBy
+    --unionBy = BS.unionBy
+    --intersectBy = BS.intersectBy
+    -- BS.groupBy is broken. groupBy f = fromList . BS.groupBy f
+    -- the below works on ghc but generates a type error on hugs
+    -- groupBy func = map fromList . L.groupBy func . toList
+    --sortBy = BS.sortBy
+    --insertBy = BS.insertBy
+    genericLength = fromInteger . fromIntegral . BS.length . unCS
+    genericTake i = CS . BS.take (fromIntegral i) . unCS
+    genericDrop i = CS . BS.drop (fromIntegral i) . unCS
+    genericSplitAt i = (CS *** CS) . BS.splitAt (fromIntegral i) . unCS
+    genericReplicate i = CS . BS.replicate (fromIntegral i)
+
+instance ListLikeIO CharString Char where
+    hGetLine h = fmap CS $ BS.hGetLine h
+    hGetContents = fmap CS . BS.hGetContents
+    hGet h n = fmap CS $ BS.hGet h n
+    hGetNonBlocking h n = fmap CS $ BS.hGetNonBlocking h n
+    hPutStr h = BS.hPut h . unCS
+    --hPutStrLn = BS.hPutStrLn
+    getLine = fmap CS BS.getLine
+    getContents = fmap CS BS.getContents
+    putStr = BS.putStr . unCS
+    putStrLn = BS.putStrLn . unCS
+    interact f = BS.interact (unCS . f . CS)
+    readFile = fmap CS . BS.readFile
+    writeFile fp = BS.writeFile fp . unCS
+    appendFile fp = BS.appendFile fp . unCS
+
+instance StringLike CharString where
+    toString = BS.unpack . unCS
+    fromString = CS . BS.pack
+
+--------------------------------------------------
+-- ByteString.Lazy
+
+-- | Newtype wrapper around Data.ByteString.Lazy.Char8.ByteString,
+--   this allows for ListLike instances with Char elements.
+newtype CharStringLazy = CSL { unCSL :: BSL.ByteString }
+  deriving (Read, Show, Eq, Ord)
+
+instance Monoid CharStringLazy where
+  mempty = CSL mempty
+  mappend l r = CSL $ mappend (unCSL l) (unCSL r)
+
+instance FoldableLL CharStringLazy Char where
+    foldl f i0  ls = BSL.foldl f i0 (unCSL ls)
+    foldl' f i0 ls = BSL.foldl' f i0 (unCSL ls)
+    foldl1 f    ls = BSL.foldl1 f (unCSL ls)
+    foldr f i0  ls = BSL.foldr f i0 (unCSL ls)
+    foldr1 f    ls = BSL.foldr1 f (unCSL ls)
+
+mi64toi :: Maybe Int64 -> Maybe Int
+mi64toi Nothing = Nothing
+mi64toi (Just x) = Just (fromIntegral x)
+
+instance ListLike CharStringLazy Char where
+    empty = CSL BSL.empty
+    singleton = CSL . BSL.singleton
+    cons x l = CSL (BSL.cons x (unCSL l))
+    snoc l x = CSL (BSL.snoc (unCSL l) x)
+    append l r = CSL $ BSL.append (unCSL l) (unCSL r)
+    head = BSL.head . unCSL
+    last = BSL.last . unCSL
+    tail = CSL . BSL.tail . unCSL
+    init = CSL . BSL.init . unCSL
+    null = BSL.null . unCSL
+    length = fromIntegral . BSL.length . unCSL
+    -- map = BSL.map
+    rigidMap f = CSL . BSL.map f . unCSL
+    reverse = CSL . BSL.reverse . unCSL
+    --intersperse = BSL.intersperse
+    concat = CSL . BSL.concat . map unCSL . toList
+    --concatMap = BSL.concatMap
+    rigidConcatMap f = CSL . BSL.concatMap (unCSL . f) . unCSL
+    any p = BSL.any p . unCSL
+    all p = BSL.all p . unCSL
+    maximum = BSL.maximum . unCSL
+    minimum = BSL.minimum . unCSL
+    replicate i = CSL . BSL.replicate (fromIntegral i)
+    take i = CSL . BSL.take (fromIntegral i) . unCSL
+    drop i = CSL . BSL.drop (fromIntegral i) . unCSL
+    splitAt i = (CSL *** CSL) . BSL.splitAt (fromIntegral i) . unCSL
+    takeWhile p = CSL . BSL.takeWhile p . unCSL
+    dropWhile p = CSL . BSL.dropWhile p . unCSL
+    span p  = (CSL *** CSL) . BSL.span p . unCSL
+    break p = (CSL *** CSL) . BSL.break p . unCSL
+    group = fromList . map CSL . BSL.group . unCSL
+    inits = fromList . map CSL . BSL.inits . unCSL
+    tails = fromList . map CSL . BSL.tails . unCSL
+    isPrefixOf p f = BSL.isPrefixOf (unCSL p) (unCSL f)
+    --isSuffixOf = BSL.isSuffixOf
+    --isInfixOf = BSL.isInfixOf
+    elem x = BSL.elem x . unCSL
+    notElem x = BSL.notElem x . unCSL
+    find p = BSL.find p . unCSL
+    filter p = CSL . BSL.filter p . unCSL
+    --partition = BSL.partition
+    index l i = BSL.index (unCSL l) (fromIntegral i)
+    elemIndex i = mi64toi . BSL.elemIndex i  . unCSL
+    --elemIndices x = fromList . L.map fromIntegral . BSL.elemIndices x
+    findIndex f = mi64toi . BSL.findIndex f . unCSL
+    --findIndices x = fromList . L.map fromIntegral . BSL.findIndices x
+    --sequence = BSL.sequence
+    --mapM = BSL.mapM
+    --mapM_ = BSL.mapM_
+    --nub = BSL.nub
+    --delete = BSL.delete
+    --deleteFirsts = BSL.deleteFirsts
+    --union = BSL.union
+    --intersect = BSL.intersect
+    --sort = BSL.sort
+    --insert = BSL.insert
+    toList = BSL.unpack . unCSL
+    fromList = CSL . BSL.pack
+    fromListLike = fromList . toList
+    --nubBy = BSL.nubBy
+    --deleteBy = BSL.deleteBy
+    --deleteFirstsBy = BSL.deleteFirstsBy
+    --unionBy = BSL.unionBy
+    --intersectBy = BSL.intersectBy
+    -- BSL.groupBy is broken. groupBy f = fromList . BSL.groupBy f
+    -- the below works on ghc but generates a type error on hugs
+    -- groupBy func = map fromList . L.groupBy func . toList
+    --sortBy = BSL.sortBy
+    --insertBy = BSL.insertBy
+    genericLength = fromInteger . fromIntegral . BSL.length . unCSL
+    genericTake i = CSL . BSL.take (fromIntegral i) . unCSL
+    genericDrop i = CSL . BSL.drop (fromIntegral i) . unCSL
+    genericSplitAt i = (CSL *** CSL) . BSL.splitAt (fromIntegral i) . unCSL
+    genericReplicate i = CSL . BSL.replicate (fromIntegral i)
+
+strict2lazy :: BS.ByteString -> CharStringLazy
+strict2lazy b = CSL $ BSL.fromChunks [b]
+
+instance ListLikeIO CharStringLazy Char where
+    hGetLine h = fmap strict2lazy $ BS.hGetLine h
+    hGetContents = fmap CSL . BSL.hGetContents
+    hGet h n = fmap CSL $ BSL.hGet h n
+    hGetNonBlocking h n = fmap CSL $ BSL.hGetNonBlocking h n
+    hPutStr h = BSL.hPut h . unCSL
+    --hPutStrLn = BSL.hPutStrLn
+    getLine = fmap strict2lazy BS.getLine
+    getContents = fmap CSL BSL.getContents
+    putStr = BSL.putStr . unCSL
+    putStrLn = BSL.putStrLn . unCSL
+    interact f = BSL.interact (unCSL . f . CSL)
+    readFile = fmap CSL . BSL.readFile
+    writeFile fp = BSL.writeFile fp . unCSL
+    appendFile fp = BSL.appendFile fp . unCSL
+
+instance StringLike CharStringLazy where
+    toString = BSL.unpack . unCSL
+    fromString = CSL . BSL.pack
