This is something of an extension to this question:
Dispatching to correct function with command line arguments in Haskell
So, as it turns out, I don’t have a good solution yet for dispatching “commands” from the command line to other functions. So, I’d like to extend the approach in the question above. It seems cumbersome to have to manually add functions to the table and apply the appropriate transformation function to each function so that it takes a list of the correct size instead of its normal arguments. Instead, I’d like to build a table where I’ll add functions and “tag” them with the number of arguments it needs to take from the command line. The “add” procedure, should then take care of composing with the correct “takesXarguments” procedure and adding it to the table.
I’d like to be able to install “packages” of functions into the table, which makes me think I need to be able to keep track of the state of the table, since it will change when packages get installed. Is the Reader Monad or the State Monad what I’m looking for?
No monad necessary. Your tagging idea is on the right track, but that information is encoded probably in a different way than you expected.
I would start with a definition of a command:
Then you can make “command maker” functions:
Which serves as the tag. If you don’t like the proliferation of functions, you can also make a “command lambda”:
So that you can write commands like:
Of course
mkCommand1etc. can be easily written in terms ofarg, for the best of both worlds.As for packages,
Commandsufficiently encapsulates choices between multiple subcommands, but they don’t compose. One option here is to changeCommandto:Which allows you to compose multiple
Commands into a single one by taking the first action that does not returnNothing. Now your packages are just values of typeCommandas well. (In general with Haskell we are very interested in these compositions — rather than packages and lists, think about how you can take two of some object to make a composite object)To save you from the desire you have surely built up: (1) there is no reasonable way to detect the number of arguments a function takes*, and (2) there is no way to make a type depend on a number, so you won’t be able to create a
mkCommandwhich takes as its first argument anIntfor the number of arguments.Hope this helped.