diff --git a/Text/JSON/Parsec.hs b/Text/JSON/Parsec.hs
--- a/Text/JSON/Parsec.hs
+++ b/Text/JSON/Parsec.hs
@@ -19,6 +19,7 @@
   , p_number
   , p_js_string
   , p_js_object
+  , p_jvalue
   , module Text.ParserCombinators.Parsec
   ) where
 
@@ -28,11 +29,14 @@
 import Data.Char
 import Numeric
 
+p_value :: CharParser () JSValue
+p_value = spaces *> p_jvalue
+
 tok              :: CharParser () a -> CharParser () a
-tok p             = spaces *> p
+tok p             = p <* spaces
 
-p_value          :: CharParser () JSValue
-p_value           =  (JSNull      <$  p_null)
+p_jvalue         :: CharParser () JSValue
+p_jvalue          =  (JSNull      <$  p_null)
                  <|> (JSBool      <$> p_boolean)
                  <|> (JSArray     <$> p_array)
                  <|> (JSString    <$> p_js_string)
@@ -51,7 +55,7 @@
 
 p_array          :: CharParser () [JSValue]
 p_array           = between (tok (char '[')) (tok (char ']'))
-                  $ p_value `sepBy` tok (char ',')
+                  $ p_jvalue `sepBy` tok (char ',')
 
 p_string         :: CharParser () String
 p_string          = between (tok (char '"')) (char '"') (many p_char)
@@ -78,7 +82,7 @@
 p_object         :: CharParser () [(String,JSValue)]
 p_object          = between (tok (char '{')) (tok (char '}'))
                   $ p_field `sepBy` tok (char ',')
-  where p_field   = (,) <$> (p_string <* tok (char ':')) <*> p_value
+  where p_field   = (,) <$> (p_string <* tok (char ':')) <*> p_jvalue
 
 p_number         :: CharParser () Rational
 p_number          = do s <- getInput
diff --git a/Text/JSON/String.hs b/Text/JSON/String.hs
--- a/Text/JSON/String.hs
+++ b/Text/JSON/String.hs
@@ -38,7 +38,6 @@
 
 import Control.Monad (liftM)
 import Data.Char (isSpace, isDigit)
-import Data.List (isPrefixOf)
 import Data.Ratio (numerator, denominator, (%))
 import Numeric (readHex, readDec, showHex)
 
@@ -81,27 +80,29 @@
 context :: String -> String
 context s = take 8 s
 
-isNullLexeme :: String -> Bool
-isNullLexeme ('n':'u':'l':'l':_) = True
-isNullLexeme _ = False
-
 -- | Read the JSON null type
 readJSNull :: GetJSON JSValue
 readJSNull = do
   xs <- getInput
-  if isNullLexeme xs 
-        then setInput (drop 4 xs) >> return JSNull
-        else fail $ "Unable to parse JSON null: " ++ context xs
+  case xs of
+    'n':'u':'l':'l':xs1 -> setInput xs1 >> return JSNull
+    _ -> fail $ "Unable to parse JSON null: " ++ context xs
 
+tryJSNull :: GetJSON JSValue -> GetJSON JSValue
+tryJSNull k = do
+  xs <- getInput
+  case xs of
+    'n':'u':'l':'l':xs1 -> setInput xs1 >> return JSNull
+    _ -> k 
+
 -- | Read the JSON Bool type
 readJSBool :: GetJSON JSValue
 readJSBool = do
   xs <- getInput
-  case () of {_
-      | "true"  `isPrefixOf` xs -> setInput (drop 4 xs) >> return (JSBool True)
-      | "false" `isPrefixOf` xs -> setInput (drop 5 xs) >> return (JSBool False)
-      | otherwise               -> fail $ "Unable to parse JSON Bool: " ++ context xs
-  }
+  case xs of
+    't':'r':'u':'e':xs1 -> setInput xs1 >> return (JSBool True)
+    'f':'a':'l':'s':'e':xs1 -> setInput xs1 >> return (JSBool False)
+    _ -> fail $ "Unable to parse JSON Bool: " ++ context xs
 
 -- | Read the JSON String type
 readJSString :: GetJSON JSValue
@@ -249,10 +250,9 @@
     '{' : _ -> readJSObject
     't' : _ -> readJSBool
     'f' : _ -> readJSBool
-    _     | isNullLexeme cs -> readJSNull
-    (x:_) | x == '-' || isDigit x  -> JSRational False <$> readJSRational
-
-    xs -> fail $ "Malformed JSON: invalid token in this context " ++ context xs
+    (x:_) | isDigit x || x == '-' -> JSRational False <$> readJSRational
+    xs -> tryJSNull
+             (fail $ "Malformed JSON: invalid token in this context " ++ context xs)
 
 -- | Top level JSON can only be Arrays or Objects
 readJSTopType :: GetJSON JSValue
diff --git a/json.cabal b/json.cabal
--- a/json.cabal
+++ b/json.cabal
@@ -1,5 +1,5 @@
 name:               json
-version:            0.4.1
+version:            0.4.2
 synopsis:           Support for serialising Haskell to and from JSON
 description:
     JSON (JavaScript Object Notation) is a lightweight data-interchange
@@ -89,10 +89,16 @@
   ghc-options:     -Wall -O2
 
   if flag(split-base)
-    build-depends:   base >= 3, array, containers, bytestring, mtl
     if flag(generic)
-      build-depends:    mtl, syb
+      build-depends:    base >=4 && <5, syb
+
       exposed-modules:  Text.JSON.Generic
+      Cpp-Options:      -DBASE_4
+    else
+      build-depends:    base >= 3
+
+    build-depends:   array, containers, bytestring, mtl
+
     if flag(parsec)
       build-depends:    parsec
       exposed-modules:  Text.JSON.Parsec
