2

I'm currently working on a library that allows the user to specify a list of command specifications as follows:

data CommandDef = forall (as :: [*]). Typeable as => CommandDef {
  argTypes :: Proxy as,
  commandName :: String,
  commandStrings :: [String],
  parsers :: HList (FMap CommandParser as),
  description :: Maybe String
}

This list of command specifications can then be passed into a template haskell function genCommands :: [CommandDef] -> Q [Dec] to generate a Command data type representing the different types of commands that the user has specified, together with a function parseCommands :: String -> Maybe Command, where argTypes specifies the types of the command's arguments to be parsed, and parsers is an HList of the relevant parsers for the given argTypes.

The issue is, I need to somehow get a Type (from Language.Haskell.TH) for each of the argTypes in a CommandDef in order to properly generate the Command type with Template Haskell -- while still keeping the type safety of making sure all of the parsers are of the appropriate type. (The idea is, if commandName = "CommandName and argTypes = Proxy @'[ArgType1, ArgType2], a constructor of form CommandName ArgType1 ArgType2 will be generated in the Command type.)

So, really, in an ideal world, what I would like is a function Proxy as -> Q [Type], or something similar, but I'm not sure if this is possible to do in Template Haskell.

Is there such a thing? Or is there any way my approach could be modified in order to accomplish all of the same goals with Template Haskell?

I have considered adding a redundant field argTypesTH :: [Name] which contains all of the names of the types in argTypes, but I'm not even sure how this could work, because I can't seem to find a template haskell function which takes a type name, and returns the needed Type that needs to be specified for the constructors of my Command type. (There is reifyType, but I'm not sure if that can do what I want, as that takes the name of a value and returns a type)

Nathan BeDell
  • 2,263
  • 1
  • 14
  • 25

0 Answers0