diff --git a/Control/Watchdog.hs b/Control/Watchdog.hs
--- a/Control/Watchdog.hs
+++ b/Control/Watchdog.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE OverloadedStrings #-}
 -- |
 -- How to use:
 --
@@ -85,6 +86,7 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 module Control.Watchdog
     ( watchdog
+    , watchdogBlank
     , watch
     , watchImpatiently
     , setInitialDelay
@@ -93,6 +95,7 @@
     , setResetDuration
     , setLoggingAction
     , defaultLogger
+    , showLogger
     , silentLogger
     , formatWatchdogError
     , WatchdogLogger
@@ -102,88 +105,91 @@
 import Control.Applicative
 import Control.Concurrent
 import Control.Monad.State.Strict
+import Data.Monoid                ((<>))
+import Data.String                (IsString, fromString)
 import Data.Time
 
-data WatchdogState = WatchdogState { wcInitialDelay   :: Int
-                                   , wcMaximumDelay   :: Int
-                                   , wcResetDuration  :: Int
-                                   , wcMaximumRetries :: Integer
-                                   , wcLoggingAction  :: WatchdogLogger
-                                   }
+data WatchdogState e = WatchdogState { wcInitialDelay   :: Int
+                                     , wcMaximumDelay   :: Int
+                                     , wcResetDuration  :: Int
+                                     , wcMaximumRetries :: Integer
+                                     , wcLoggingAction  :: WatchdogLogger e
+                                     }
 
-data WatchdogTaskStatus a = FailedImmediately String
-                          | FailedAfterAWhile String
-                          | CompletedSuccessfully a
+data WatchdogTaskStatus e a = FailedImmediately e
+                            | FailedAfterAWhile e
+                            | CompletedSuccessfully a
 
-newtype WatchdogAction a = WA { runWA :: StateT WatchdogState IO a }
-                           deriving ( Functor, Applicative, Alternative
-                                    , Monad, MonadIO, MonadState WatchdogState)
+newtype WatchdogAction e a = WA { runWA :: StateT (WatchdogState e) IO a }
+                             deriving ( Functor, Applicative, Alternative
+                                      , Monad, MonadIO, MonadState (WatchdogState e))
 
 -- | Type synonym for a watchdog logger.
-type WatchdogLogger = String     -- ^ Error message returned by the task.
-                    -> Maybe Int -- ^ Waiting time - if any - before trying again.
-                    -> IO ()
+type WatchdogLogger e = e          -- ^ Error value returned by the task.
+                      -> Maybe Int -- ^ Waiting time - if any - before trying again.
+                      -> IO ()
 
-defaultConf :: WatchdogState
-defaultConf = WatchdogState { wcInitialDelay = 1 * 10 ^ (6::Integer)
-                            , wcMaximumDelay = 300 * 10 ^ (6::Integer)
-                            , wcMaximumRetries = 10
-                            , wcResetDuration = 30 * 10 ^ (6::Integer)
-                            , wcLoggingAction = defaultLogger
-                            }
+defaultConf :: WatchdogState String
+defaultConf = blankConf { wcLoggingAction = defaultLogger }
 
+blankConf :: WatchdogState e
+blankConf = WatchdogState { wcInitialDelay   = 1 * 10 ^ (6::Integer)
+                          , wcMaximumDelay   = 300 * 10 ^ (6::Integer)
+                          , wcMaximumRetries = 10
+                          , wcResetDuration  = 30 * 10 ^ (6::Integer)
+                          , wcLoggingAction  = silentLogger
+                          }
+
 -- | The Watchdog monad. Used to configure and eventually run a watchdog.
-watchdog :: WatchdogAction a -> IO a
-watchdog action = evalStateT (runWA action) defaultConf
+watchdog :: WatchdogAction String a -> IO a
+watchdog = watchdogWith defaultConf
 
+-- | As with 'watchdog', but don't specify a default logging action to
+--   allow it to be polymorphic.
+watchdogBlank :: WatchdogAction e a -> IO a
+watchdogBlank = watchdogWith blankConf
+
+watchdogWith :: WatchdogState e -> WatchdogAction e a -> IO a
+watchdogWith conf action = evalStateT (runWA action) conf
+
 -- | Set the initial delay in microseconds. The first time the watchdog pauses
 -- will be for this amount of time. The default is 1 second.
-setInitialDelay :: Int -> WatchdogAction ()
-setInitialDelay delay = do
-    conf <- get
-    put conf { wcInitialDelay = delay }
+setInitialDelay :: Int -> WatchdogAction e ()
+setInitialDelay delay = modify (\conf -> conf { wcInitialDelay = delay })
 
 -- | Set the maximum delay in microseconds. When a task fails to execute
 -- properly multiple times in quick succession, the delay is doubled each time
 -- until it stays constant at the maximum delay. The default is 300 seconds.
-setMaximumDelay :: Int -> WatchdogAction ()
-setMaximumDelay delay = do
-    conf <- get
-    put conf { wcMaximumDelay = delay }
+setMaximumDelay :: Int -> WatchdogAction e ()
+setMaximumDelay delay = modify (\conf -> conf { wcMaximumDelay = delay })
 
 -- | If a task has been running for some time, the watchdog will consider
 -- the next failure to be something unrelated and reset the waiting time
 -- back to the initial delay. This function sets the amount of time in
 -- microseconds that needs to pass before the watchdog will consider a task to
 -- be successfully running. The default is 30 seconds.
-setResetDuration :: Int -> WatchdogAction ()
-setResetDuration duration = do
-    conf <- get
-    put conf { wcResetDuration = duration }
+setResetDuration :: Int -> WatchdogAction e ()
+setResetDuration duration = modify (\conf -> conf { wcResetDuration = duration })
 
 -- | Set the number of retries after which the watchdog will give up and
 -- return with a permanent error. This setting is only used in combination with
 -- 'watchImpatiently'. The default is 10.
-setMaximumRetries :: Integer -> WatchdogAction ()
-setMaximumRetries retries = do
-    conf <- get
-    put conf { wcMaximumRetries = retries }
+setMaximumRetries :: Integer -> WatchdogAction e ()
+setMaximumRetries retries = modify (\conf -> conf { wcMaximumRetries = retries })
 
 -- | Set the logging action that will be called by the watchdog. The supplied
 -- function of type 'WatchdogLogger' will be provided with the error message of
 -- the task and either 'Nothing' if the watchdog will retry immediately or 'Just
 -- delay' if the watchdog will now pause for the specified amount of time before
 -- trying again.  The default is 'defaultLogger'.
-setLoggingAction :: WatchdogLogger -> WatchdogAction ()
-setLoggingAction f = do
-    conf <- get
-    put conf { wcLoggingAction = f }
+setLoggingAction :: WatchdogLogger e -> WatchdogAction e ()
+setLoggingAction f = modify (\conf -> conf { wcLoggingAction = f })
 
 -- | Watch a task, restarting it potentially forever or until it returns with a
 -- result. The task should return an 'Either', where 'Left' in combination with
 -- an error message signals an error and 'Right' with an arbitrary result
 -- signals success.
-watch :: IO (Either String a) -> WatchdogAction a
+watch :: IO (Either e a) -> WatchdogAction e a
 watch task = do
     conf <- get
     liftIO $ go conf (wcInitialDelay conf)
@@ -209,41 +215,45 @@
 -- | Watch a task, but only restart it a limited number of times (see
 -- 'setMaximumRetries'). If the failure persists, it will be returned as a 'Left',
 -- otherwise it will be 'Right' with the result of the task.
-watchImpatiently :: IO (Either String b) -> WatchdogAction (Either String b)
+watchImpatiently :: IO (Either e b) -> WatchdogAction e (Either e b)
 watchImpatiently task = do
     conf <- get
-    liftIO $ go conf 0 "" (wcInitialDelay conf)
+    liftIO $ go conf 0 (wcInitialDelay conf)
   where
-    go conf retries lastError errorDelay = do
+    go conf retries errorDelay = do
         status <- timeTask (wcResetDuration conf) task
         case status of
             CompletedSuccessfully result -> return $ Right result
             FailedAfterAWhile err ->
                 if retries >= wcMaximumRetries conf
-                    then return $ Left lastError
+                    then return $ Left err
                     else do
                         let errorDelay' = wcInitialDelay conf
                             loggingAction = wcLoggingAction conf
                         loggingAction err Nothing
-                        go conf (retries + 1) err errorDelay'
+                        go conf (retries + 1) errorDelay'
             FailedImmediately err ->
                 if retries >= wcMaximumRetries conf
-                    then return $ Left lastError
+                    then return $ Left err
                     else do
                         let errorDelay' =
                                 min (errorDelay * 2) (wcMaximumDelay conf)
                             loggingAction = wcLoggingAction conf
                         loggingAction err (Just errorDelay)
                         threadDelay errorDelay
-                        go conf (retries + 1) err errorDelay'
+                        go conf (retries + 1) errorDelay'
 
 -- | The default logging action. It will call 'formatWatchdogError' and display
 -- the result on STDOUT.
-defaultLogger :: WatchdogLogger
+defaultLogger :: WatchdogLogger String
 defaultLogger taskErr delay = putStrLn $ formatWatchdogError taskErr delay
 
+-- | As with 'defaultLogger', but calls 'show' on the value provided.
+showLogger :: (Show e) => WatchdogLogger e
+showLogger err = defaultLogger (show err)
+
 -- | Disable logging by passing this function to 'setLoggingAction'.
-silentLogger :: WatchdogLogger
+silentLogger :: WatchdogLogger e
 silentLogger _ _ = return ()
 
 -- | Format the watchdog status report. Will produce output like this:
@@ -252,16 +262,17 @@
 -- Watchdog: Error executing task (some error) - trying again immediately.
 -- Watchdog: Error executing task (some error) - waiting 1s before trying again.
 -- @
-formatWatchdogError :: String -- ^ Error message returned by the task.
-                    -> Maybe Int -- ^ Waiting time - if any - before trying again.
-                    -> String
+formatWatchdogError :: (IsString str, Monoid str)
+                       => str       -- ^ Error message returned by the task.
+                       -> Maybe Int -- ^ Waiting time - if any - before trying again.
+                       -> str
 formatWatchdogError taskErr Nothing =
-    "Watchdog: Error executing task (" ++ taskErr ++ ") - trying again immediately."
+    "Watchdog: Error executing task (" <> taskErr <> ") - trying again immediately."
 formatWatchdogError taskErr (Just delay) =
     let asNominalDiffTime :: NominalDiffTime    -- just to display it properly
         asNominalDiffTime = fromIntegral delay / 10 ^ (6 :: Integer)
-    in "Watchdog: Error executing task (" ++ taskErr ++ ") - waiting"
-        ++ " " ++ show asNominalDiffTime ++ " before trying again."
+    in "Watchdog: Error executing task (" <> taskErr <> ") - waiting"
+        <> " " <> fromString (show asNominalDiffTime) <> " before trying again."
 
 -- | Helper class which can be wrapped around a task.
 -- The task should return an 'Either', where Left in combination
@@ -269,7 +280,7 @@
 -- result signals success. In case of failure, the wrapper will check whether
 -- the function ran less than 30 seconds and then return 'FailedImmediately'
 -- or 'FailedAfterAWhile' accordingly.
-timeTask :: Int -> IO (Either String a) -> IO (WatchdogTaskStatus a)
+timeTask :: Int -> IO (Either e a) -> IO (WatchdogTaskStatus e a)
 timeTask resetDuration task = do
     start <- getCurrentTime
     status <- task
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2012 - 2014, Jan Vornberger
+Copyright (c) 2012 - 2017, Jan Vornberger
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/watchdog.cabal b/watchdog.cabal
--- a/watchdog.cabal
+++ b/watchdog.cabal
@@ -1,5 +1,5 @@
 name:           watchdog
-version:        0.2.3
+version:        0.3
 author:         Jan Vornberger <jan@uos.de>
 copyright:      (c) 2012 - 2017 Jan Vornberger
 maintainer:     Jan Vornberger <jan@uos.de>
@@ -17,7 +17,7 @@
     location: https://github.com/javgh/watchdog
 
 library
-    build-depends: base == 4.*
+    build-depends: base >= 4.5 && < 5
                    , time >= 1.4 && < 1.9
                    , mtl >= 2.1 && < 2.3
     exposed-modules: Control.Watchdog
