diff --git a/base-prelude.cabal b/base-prelude.cabal
--- a/base-prelude.cabal
+++ b/base-prelude.cabal
@@ -1,7 +1,7 @@
 name:
   base-prelude
 version:
-  0.1.9
+  0.1.10
 synopsis:
   The most complete prelude formed from only the "base" package
 description:
diff --git a/library/BasePrelude.hs b/library/BasePrelude.hs
--- a/library/BasePrelude.hs
+++ b/library/BasePrelude.hs
@@ -15,6 +15,9 @@
   traceShowM,
   -- ** Data.Ord
   Down(..),
+  -- ** Text.Read
+  readEither,
+  readMaybe,
 )
 where
 
@@ -66,9 +69,12 @@
 import System.Mem as Exports
 import System.Mem.StableName as Exports
 import System.Timeout as Exports
-import Text.Read as Exports (readMaybe, readEither)
+import Text.Read as Exports (Read(..))
 import Unsafe.Coerce as Exports
 
+import qualified Text.ParserCombinators.ReadPrec as ReadPrec
+import qualified Text.ParserCombinators.ReadP as ReadP
+
 -- Reimplementations
 -------------------------
 
@@ -120,3 +126,26 @@
 
 instance Ord a => Ord (Down a) where
   compare (Down x) (Down y) = y `compare` x
+
+
+-- | Parse a string using the 'Read' instance.
+-- Succeeds if there is exactly one valid result.
+-- A 'Left' value indicates a parse error.
+readEither :: Read a => String -> Either String a
+readEither s =
+  case [ x | (x,"") <- ReadPrec.readPrec_to_S read' ReadPrec.minPrec s ] of
+    [x] -> Right x
+    []  -> Left "Prelude.read: no parse"
+    _   -> Left "Prelude.read: ambiguous parse"
+  where
+    read' =
+      do x <- readPrec
+         ReadPrec.lift ReadP.skipSpaces
+         return x
+
+-- | Parse a string using the 'Read' instance.
+-- Succeeds if there is exactly one valid result.
+readMaybe :: Read a => String -> Maybe a
+readMaybe s = case readEither s of
+                Left _  -> Nothing
+                Right a -> Just a
