diff --git a/bookhound.cabal b/bookhound.cabal
--- a/bookhound.cabal
+++ b/bookhound.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           bookhound
-version:        0.1.14.0
+version:        0.1.15.0
 synopsis:       Simple Parser Combinators
 description:    Please see the README on GitHub at <https://github.com/albertprz/bookhound#readme>
 category:       Parser Combinators
diff --git a/src/Bookhound/Parser.hs b/src/Bookhound/Parser.hs
--- a/src/Bookhound/Parser.hs
+++ b/src/Bookhound/Parser.hs
@@ -1,6 +1,6 @@
 module Bookhound.Parser (Parser, ParseResult, ParseError(..), runParser, errorParser,
                andThen, exactly, isMatch, check, anyOf, allOf, char,
-               withTransform, withError, except) where
+               withTransform, withError, withErrorFrom, except) where
 
 import Bookhound.Utils.Foldable (findJust)
 import Control.Applicative      (liftA2)
@@ -29,21 +29,26 @@
   | UnexpectedString String
   | NoMatch String
   | ErrorAt String
-  deriving (Eq, Show)
+  deriving (Eq)
 
 
 instance Show a => Show (ParseResult a) where
-  show (Result i a)                 = "Pending: " <> " >" <> unpack i <> "< " <>
-                                      "\n\nResult: \n" <> show a
-  show (Error UnexpectedEof)        = "Unexpected end of stream"
-  show (Error (ExpectedEof i))      = "Expected end of stream, but got >"
-                                       <> unpack i <> "<"
-  show (Error (UnexpectedChar c))   = "Unexpected char: "   <> "[" <> show c <> "]"
-  show (Error (UnexpectedString s)) = "Unexpected string: " <> "[" <> show s <> "]"
-  show (Error (NoMatch s))          = "Did not match condition: " <> s
-  show (Error (ErrorAt s))          = "Error at " <> s
+  show (Result i a) = "Pending: " <> " >" <> unpack i <> "< "
+                                  <> "\n\nResult: \n" <> show a
+  show (Error err)  = show err
 
+instance Show ParseError where
+  show UnexpectedEof        = "Unexpected end of stream"
+  show (ExpectedEof i)      = "Expected end of stream, but got "
+                               <> ">" <> unpack i <> "<"
+  show (UnexpectedChar c)   = "Unexpected char: "
+                               <> "[" <> show c <> "]"
+  show (UnexpectedString s) = "Unexpected string: "
+                               <> "[" <> s <> "]"
+  show (NoMatch s)          = "Did not match condition: " <> s
+  show (ErrorAt s)          = "Error at " <> s
 
+
 instance Functor ParseResult where
   fmap f (Result i a) = Result i (f a)
   fmap _ (Error pe)   = Error pe
@@ -160,6 +165,11 @@
 
 withError :: String -> Parser a -> Parser a
 withError = applyError . pure . ErrorAt
+
+withErrorFrom :: (a -> String) -> Parser a -> Parser a
+withErrorFrom errFn p =
+  do val <- p
+     withError (errFn val) p
 
 withTransform :: (forall b. Parser b -> Parser b) -> Parser a -> Parser a
 withTransform t = applyTransform $ Just t
