{-# 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 Text.PrettyPrint import Prelude hiding (mod) -- | 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' @\@ -- 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} = render $ {- text package <> char '.' <> -} text mod <> parens (text filename) <> colon <+> text (show start)