diff --git a/Data/ByteString/Char8.hs b/Data/ByteString/Char8.hs
--- a/Data/ByteString/Char8.hs
+++ b/Data/ByteString/Char8.hs
@@ -266,6 +266,10 @@
 import GHC.ST                   (ST(..))
 #endif
 
+#if __GLASGOW_HASKELL__ >= 608
+import Data.String
+#endif
+
 #define STRICT1(f) f a | a `seq` False = undefined
 #define STRICT2(f) f a b | a `seq` b `seq` False = undefined
 #define STRICT3(f) f a b c | a `seq` b `seq` c `seq` False = undefined
@@ -277,6 +281,12 @@
 singleton :: Char -> ByteString
 singleton = B.singleton . c2w
 {-# INLINE singleton #-}
+
+#if __GLASGOW_HASKELL__ >= 608
+instance IsString ByteString where
+    fromString = pack
+    {-# INLINE fromString #-}
+#endif
 
 -- | /O(n)/ Convert a 'String' into a 'ByteString'
 --
diff --git a/Data/ByteString/Lazy/Char8.hs b/Data/ByteString/Lazy/Char8.hs
--- a/Data/ByteString/Lazy/Char8.hs
+++ b/Data/ByteString/Lazy/Char8.hs
@@ -218,6 +218,10 @@
 import IO                   (bracket)
 #endif
 
+#if __GLASGOW_HASKELL__ >= 608
+import Data.String
+#endif
+
 #define STRICT1(f) f a | a `seq` False = undefined
 #define STRICT2(f) f a b | a `seq` b `seq` False = undefined
 #define STRICT3(f) f a b c | a `seq` b `seq` c `seq` False = undefined
@@ -231,6 +235,12 @@
 singleton = L.singleton . c2w
 {-# INLINE singleton #-}
 
+#if __GLASGOW_HASKELL__ >= 608
+instance IsString ByteString where
+    fromString = pack
+    {-# INLINE fromString #-}
+#endif
+
 -- | /O(n)/ Convert a 'String' into a 'ByteString'. 
 pack :: [Char] -> ByteString
 pack = L.pack. List.map c2w
@@ -643,6 +653,9 @@
 -- | 'lines' breaks a ByteString up into a list of ByteStrings at
 -- newline Chars. The resulting strings do not contain newlines.
 --
+-- As of bytestring 0.9.0.3, this function is stricter than its 
+-- list cousin.
+--
 lines :: ByteString -> [ByteString]
 lines Empty          = []
 lines (Chunk c0 cs0) = loop0 c0 cs0
@@ -659,7 +672,6 @@
     -- the common special case where we have no existing chunks of
     -- the current line
     loop0 :: B.ByteString -> ByteString -> [ByteString]
-    STRICT2(loop0)
     loop0 c cs =
         case B.elemIndex (c2w '\n') c of
             Nothing -> case cs of
@@ -677,7 +689,6 @@
     -- the general case when we are building a list of chunks that are
     -- part of the same line
     loop :: B.ByteString -> [B.ByteString] -> ByteString -> [ByteString]
-    STRICT3(loop)
     loop c line cs =
         case B.elemIndex (c2w '\n') c of
             Nothing ->
@@ -690,6 +701,30 @@
             Just n ->
                 let c' = revChunks (B.unsafeTake n c : line)
                  in c' `seq` (c' : loop0 (B.unsafeDrop (n+1) c) cs)
+
+{-
+
+This function is too strict!  Consider,
+
+> prop_lazy =
+    (L.unpack . head . lazylines $ L.append (L.pack "a\nb\n") (error "failed"))
+  ==
+    "a"
+
+fails.  Here's a properly lazy version of 'lines' for lazy bytestrings
+
+    lazylines           :: L.ByteString -> [L.ByteString]
+    lazylines s
+        | L.null s  = []
+        | otherwise =
+            let (l,s') = L.break ((==) '\n') s
+            in l : if L.null s' then []
+                                else lazylines (L.tail s')
+
+we need a similarly lazy, but efficient version.
+
+-}
+
 
 -- | 'unlines' is an inverse operation to 'lines'.  It joins lines,
 -- after appending a terminating newline to each.
diff --git a/bytestring.cabal b/bytestring.cabal
--- a/bytestring.cabal
+++ b/bytestring.cabal
@@ -1,5 +1,5 @@
 Name:                bytestring
-Version:             0.9.0.3
+Version:             0.9.0.4
 Synopsis:            Fast, packed, strict and lazy byte arrays with a list interface
 Description:
     .
