monadloc-0.6: Control/Monad/Loc.hs
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-|
This package defines a MonadLoc class for monads which support Monadic Call Traces.
See http://pepeiborra.posterous.com/monadic-stack-traces-that-make-a-lot-of-sense
* Traces are only provided for explicitly annotated program points.
* This package installs the MonadLoc preprocessor for this purpose.
To enable it include the following pragma at the top of your haskell source files:
@
{ -\# OPTIONS_GHC -F -pgmF MonadLoc \#- }
@
* There is also the TH macro 'withLocTH' to manually annotate program points,
but you should always use the preprocessor if possible.
-}
module Control.Monad.Loc (MonadLoc(..), withLocTH) where
import Language.Haskell.TH.Syntax (qLocation, Loc(..), Q, Exp)
import Prelude hiding (mod)
import Text.Printf
-- | Generating stack traces for failures
class Monad m => MonadLoc m where
-- | 'withLoc' records the given source location in the failure trace
-- if the underlying monad supports recording location traces
--
withLoc :: String -> m a -> m a
instance Monad m => MonadLoc m where withLoc _ = id;
-- | 'withLocTH' is a convenient TH macro which expands to 'withLoc' @\<source location\>@
-- It should only be used when the MonadLoc preprocessor is not available.
-- Usage:
--
-- > f x = $withLocTH $ do
-- > $withLocTH $ something
-- > x < -$withLocTH $ something-else
-- > ...
--
-- NOTE: unfortunately type signatures are necessary when using withLocTH
withLocTH :: Q Exp
withLocTH = do
loc <- qLocation
let loc_msg = showLoc loc
[| withLoc loc_msg |]
showLoc :: Loc -> String
showLoc Loc{loc_module=mod, loc_filename=filename, loc_start=start} =
{- text package <> char '.' <> -}
printf "%s (%s). %s" mod filename (show start)