module Language.MSH.CodeGen.Monad ( genStateType ) where import Language.Haskell.TH import Language.Haskell.TH.Syntax import Language.MSH.StateDecl import Language.MSH.CodeGen.Shared import Language.MSH.CodeGen.Interop genStateType :: [TyVarBndr] -> StateDecl -> Q Dec genStateType tyvars (StateDecl { stateName = name, stateParams = vars, stateParentN = mp }) = do let -- unlike in the paper, the type synonym isn't just the name of the class tname = mkName $ name ++ "M" stype = appN (ConT (mkName $ name ++ "State")) vars case mp of Nothing -> return $ TySynD tname tyvars (AppT (ConT (mkName "State")) stype) (Just p) -> do let ptype = parseType p -- we want the monad, not the object fixpt t@(ConT _) = renameT (\n -> n ++ "M") t fixpt (AppT f a) = AppT (fixpt f) a return $ TySynD tname tyvars (AppT (AppT (ConT (mkName "StateT")) stype) (fixpt ptype))