module GenDataTypes where import Language.Haskell.TH import Language.Haskell.TH.Syntax import GetTypes import Data.List {- - makeType: - - Converts a string and a list of strings into a declaration for a new type. For example, if given the arguments: - - "T0" ["Male", "Female"] - - the declaration: - - data T0 = Male | Female deriving (Read, Show, Eq, Bounded, Enum) - - will be returned. -} makeType dsName consList = let constructors = map (flip (normalC . mkName) []) consList -- Create a list of type constructors from the representing list of strings. stripName = delete listClose (tail dsName) -- Remove the list open and close symbols from the data type name (if they're there). useName = if ((head dsName) /= listOpen) then dsName else stripName -- Select whether or not to use the stripped name or the original name. in dataD (cxt []) (mkName useName) [] constructors [(mkName "Read"), (mkName "Show"), (mkName "Eq"), (mkName "Bounded"), (mkName "Enum")] -- Return the declaration. {- - makeTypeSyn: - - Takes a string and a list of strings and makes a type synonym declaration for the tuple of them. For example, with the arguments: - - "MainType" ["String", "Float", "Int", "T0"] - - the following declaration is returned: - - type MainType = (Maybe String, Maybe Float, Maybe Int, Maybe T0) -} makeTypeSyn tName typeList = let createType typeList = doCreateType (reverse typeList) (length typeList) -- Reverses the list and runs the doCreateType function on it. in tySynD (mkName tName) [] (createType typeList) {- - doCreateType: - - Converts a list of strings into a tuple representation of Maybe types. -} doCreateType [x] tupSize = let stripName = delete listClose (tail x) -- Strips the list open and close symbols. constructor = if ((head x) /= listOpen) then (conT (mkName x)) else (appT listT (conT (mkName stripName))) -- If the type is a list then convert it to the representation of a list. Otherwise just use the name given. in appT (tupleT tupSize) (appT (conT (mkName "Maybe")) constructor) -- Finish the creation of the tuple. doCreateType (x:xs) tupSize = let stripName = delete listClose (tail x) constructor = if ((head x) /= listOpen) then (conT (mkName x)) else (appT listT (conT (mkName stripName))) in appT (doCreateType xs tupSize) (appT (conT (mkName "Maybe")) constructor) -- Join Maybe and the type name to the rest of the tuple.