diff --git a/Text/Regex/PCRE/Light.hs b/Text/Regex/PCRE/Light.hs
--- a/Text/Regex/PCRE/Light.hs
+++ b/Text/Regex/PCRE/Light.hs
@@ -80,8 +80,6 @@
 import qualified Data.ByteString.Base     as S
 #endif
 
-import Control.Monad
-
 -- Foreigns
 import Foreign
 import Foreign.Ptr
@@ -177,30 +175,15 @@
 --
 compile :: S.ByteString -> [PCREOption] -> Regex
 compile s o = case compileM s o of
-    Just  r -> r
-    Nothing -> error ("Text.Regex.PCRE.Light: Error in regex: " ++ show s)
+    Right r -> r
+    Left  s -> error ("Text.Regex.PCRE.Light: Error in regex: " ++ s)
 
 ------------------------------------------------------------------------
 
 -- | 'compileM'
--- A generic version of 'compile' with failure lifted into an arbitrary monad.
---
--- Examples, illustrating how failure can be propagated to an IO exception, 
--- or tagged as 'Nothing':
---
--- > > compileM ".*" [] :: Maybe Regex
--- > Just (Regex 0x000000004bb5b540 ".*")
---
--- > > compileM "*" [] :: Maybe Regex
--- > Nothing
---
--- > > compileM "*" [] :: IO Regex
--- > *** Exception: user error (nothing to repeat)
---
--- > > compileM ".*" [] :: IO Regex
--- > Regex 0x000000004bb5b780 ".*"
+-- A safe version of 'compile' with failure wrapped in an Either.
 --
--- > > :m + Control.Monad.Error
+-- Examples,
 --
 -- > > compileM ".*" [] :: Either String Regex
 -- > Right (Regex 0x000000004bb5b980 ".*")
@@ -208,7 +191,7 @@
 -- > > compileM "*" [] :: Either String Regex
 -- > Left "nothing to repeat"
 --
-compileM :: Monad m => S.ByteString -> [PCREOption] -> m Regex
+compileM :: S.ByteString -> [PCREOption] -> Either String Regex
 compileM str os = unsafePerformIO $
   S.useAsCString str $ \pattern -> do
     alloca $ \errptr       -> do
@@ -217,10 +200,10 @@
         if pcre_ptr == nullPtr
             then do
                 err <- peekCString =<< peek errptr
-                return (fail err)
+                return (Left err)
             else do
                 reg <- newForeignPtr finalizerFree pcre_ptr -- release with free()
-                return (return (Regex reg str))
+                return (Right (Regex reg str))
 
 -- Possible improvements: an 'IsString' instance could be defined
 -- for 'Regex', which would allow the compiler to insert calls to
diff --git a/Text/Regex/PCRE/Light/Char8.hs b/Text/Regex/PCRE/Light/Char8.hs
--- a/Text/Regex/PCRE/Light/Char8.hs
+++ b/Text/Regex/PCRE/Light/Char8.hs
@@ -143,8 +143,8 @@
 {-# INLINE compile #-}
 
 -- | 'compileM'
--- A generic version of 'compile' with failure lifted into an arbitrary monad.
-compileM :: Monad m => String -> [PCREOption] -> m Regex
+-- A safe version of 'compile' with failure lifted into an Either
+compileM :: String -> [PCREOption] -> Either String Regex
 compileM str os = S.compileM (S.pack str) os
 {-# INLINE compileM #-}
 
diff --git a/pcre-light.cabal b/pcre-light.cabal
--- a/pcre-light.cabal
+++ b/pcre-light.cabal
@@ -1,5 +1,5 @@
 name:            pcre-light
-version:         0.2.1
+version:         0.3
 homepage:        http://code.haskell.org/~dons/code/pcre-light
 synopsis:        A small, efficient and portable regex library for Perl 5 compatible regular expressions
 description:
diff --git a/tests/Makefile b/tests/Makefile
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -3,7 +3,7 @@
 #	runhaskell Unit.hs && echo $$?
 
 test::
-	ghc -fhpc --make -i.. Unit.hs -o Unit -O2 -no-recomp
+	ghc -ddump-simpl-stats -lpcre -fhpc --make -i.. -i../dist/build/ Unit.hs -o Unit -O2 -no-recomp
 	rm -f *.tix
 	./Unit 
 	hpc report --decl-list       --exclude=Main Unit
diff --git a/tests/Unit.hs b/tests/Unit.hs
--- a/tests/Unit.hs
+++ b/tests/Unit.hs
@@ -1,7 +1,8 @@
 {-# LANGUAGE OverloadedStrings #-}
 
-import Text.Regex.PCRE.Light
-import qualified Text.Regex.PCRE.Light.Char8 as String
+import Text.Regex.PCRE.Light (compile,compileM,match)
+import qualified Text.Regex.PCRE.Light.Char8 as String (compile,compileM,match)
+import Text.Regex.PCRE.Light.Base 
 
 import qualified Data.ByteString.Char8 as S
 import System.IO
@@ -17,40 +18,49 @@
 import Control.Exception
 import Control.Monad.Error
 
+assertBool'  s = assertBool  (S.unpack s)
+assertEqual' s = assertEqual (S.unpack s)
+
+testLabel  s = TestLabel (S.unpack s)
+
+instance Error S.ByteString where
+    noMsg = S.empty
+    strMsg = S.pack
+
 testRegex :: S.ByteString
      -> [PCREOption]
      -> [S.ByteString]
      -> [Maybe [S.ByteString]]
      -> Test
 
-testRegex regex options inputs outputs = TestLabel (S.unpack regex) $
+testRegex regex options inputs outputs = testLabel regex $
   TestCase $ do
-     assertEqual "Input/Output Length Check" (length inputs) (length outputs)
+     assertEqual' "Input/Output Length Check" (length inputs) (length outputs)
 
-     assertBool "ByteString regex compile" =<<
+     assertBool' "ByteString regex compile" =<<
       case compile regex options of
         r -> return $
             and [ match r i [] == o
                 | (i,o) <- zip inputs outputs ]
 
-     assertBool "ByteString regex compileM" =<<
+     assertBool' "ByteString regex compileM" =<<
       case compileM regex options of
-        Left s -> do hPutStrLn stderr ("ERROR in ByteString in compileM: " ++ s)
+        Left s -> do S.hPutStrLn stderr ("ERROR in ByteString in compileM " `S.append` (S.pack s))
                      return False
         Right r -> return $
             and [ match r i [] == o
                 | (i,o) <- zip inputs outputs ]
 
-     assertBool "String regex" =<<
+     assertBool' "String regex" =<<
       case String.compile (S.unpack regex) options of
         r -> return $
             and [ String.match r i [] == o
                 | (i,o) <- zip (map (S.unpack) inputs)
                                (map (fmap (map S.unpack)) outputs) ]
 
-     assertBool "String regex" =<<
+     assertBool' "String regex" =<<
       case String.compileM (S.unpack regex) options of
-        Left s -> do hPutStrLn stderr ("ERROR in String compileM: "  ++ s)
+        Left s -> do S.hPutStrLn stderr ("ERROR in String compileM: " `S.append` (S.pack s))
                      return False
         Right r -> return $
             and [ String.match r i [] == o
@@ -74,16 +84,16 @@
            , Nothing
            ]
 
-    , TestLabel "compile failure" $
-            TestCase $ (assertBool "compile failure" $
-                Left ("nothing to repeat"::String) == compileM "*" [])
+    , testLabel "compile failure" $
+            TestCase $ (assertBool' "compile failure" $
+                Left ("nothing to repeat" ) == compileM "*" [])
 
-    , TestLabel "compile failure" $
-            TestCase $ (assertBool "compile failure" =<< (return $
-                    (Just ("Text.Regex.PCRE.Light: Error in regex: \"*\""::String))
+    , testLabel "compile failure" $
+            TestCase $ (assertBool' "compile failure" =<< (return $
+                    (Just ("Text.Regex.PCRE.Light: Error in regex: nothing to repeat"))
                     ==
                     (unsafePerformIO $ do
-                        handle (\e -> return (Just (show e)))
+                        handle (\e -> return (Just (S.pack $ show e)))
                                (compile "*" [] `seq` return Nothing))))
 
 --  , testRegex "\0*" [] -- the embedded null in the pattern seems to be a problem
