-- | The main TH driver module. It is intended that this need be the -- only module imported by user code; it takes care of all data -- threading issues such that all one needs to do is: -- -- @ -- data Foo = Foo ; $( derive makeEq ''Foo ) -- @ module Data.DeriveTH(derive, derives, deriveFromDec, module Data.Derive.All) where import Control.Monad import Data.Derive.All import Data.Derive.Internal.Derivation import Language.Haskell.TH.All as TH hiding (Derivation(..),toName) import Language.Haskell as HS import Language.Haskell.Convert -- | Derive an instance of some class. @derive@ only derives instances -- for the type of the argument. derive :: Derivation -> TH.Name -> Q [Dec] derive d name = do x <- reify name case x of TyConI dec -> deriveFromDec d dec _ -> error $ "Data.DeriveTH.derive: Expected a data type declaration, got:\n" ++ show x derives :: [Derivation] -> [TH.Name] -> Q [Dec] derives xs ys = liftM concat $ sequence [derive x y | y <- ys, x <- xs] -- | Derive an instance of some class. @deriveFromDec@ only derives instances -- for the type of the argument. deriveFromDec :: Derivation -> Dec -> Q [Dec] deriveFromDec d x = do x <- liftM normData $ expandData x let unsup x = error $ "Derivation of " ++ derivationName d ++ " does not yet support Template Haskell, requires info for " ++ x case derivationOp d (tyCon $ derivationName d) unsup $ toFullDataDecl x of Left y -> runIO (putStrLn $ "Warning, couldn't derive: " ++ y) >> return [] Right v -> return $ convert v toFullDataDecl :: Dec -> FullDataDecl toFullDataDecl x = (ModuleName "Todo", convert x)