pattern matching against string based commands https://github.com/jsdw/hs-commander
|Latest on Hackage:||0.1.0.0|
This package is not currently in any snapshots. If you're interested in using it, we recommend adding it to Stackage Nightly. Doing so will make builds more reliable, and allow stackage.org to host generated Haddocks.
Commander: A Haskell Library for parsing commands
This library aims to make it super easy to create and use nested commands with flags in the form of an object that is easy to traverse and run custom actions on, and easy to extend with handling for safe casting to values from their input strings.
As an example of usage (take a look in the examples folder for more) we can define commands as follows:
someCommands :: Command (IO ()) someCommands = commands $ do command "repeat" $ do help "Repeat a string n times" run $ \(Value str :: Value "value to repeat" String) (Flag n :: Flag '["n"] "times to repeat" Int) -> sequence_ $ replicate n (putStrLn str) command "calculate" $ do help "perform calculations" command "add" $ do help "add two numbers" run $ \(Value n1 :: Value "number 1" Int) (Value n2 :: Value "number 2" Int) (Flag verbose :: Flag '["v", "verbose"] "verbose mode" Bool) -> if verbose then putStrLn $ (show n1) ++ " + " ++ (show n2) ++ " = " ++ (show $ n1 + n2) else putStrLn (show $ n1 + n2) command "multiply" $ do help "multiply two numbers" run $ \(Value n1 :: Value "number 1" Int) (Value n2 :: Value "number 2" Int) -> putStrLn $ (show n1) ++ " x " ++ (show n2) ++ " = " ++ (show $ n1 * n2)
And this leads to
someCommands being a nested record of type
Command (IO ()) (where
IO () corresponds to the output from the functions you provide). This record can then be traversed and interacted with.
The novelty of this approach (compared to others I have seen, which is a non exhaustive list!) is the use of the functions input parameter types to cast-from-string and inject the appropriate values into the function safely at runtime, as well as to generate documentation. This means that we only declare the flags and values each command requires in one place, and do not execute any of the output unless all parameters are fully satisfied. These functions are then safely hidden away inside an existential type, and so we don't need any other type level magic or handling to work with the output.
Add this repository to your stack.yaml file under the packages folder, so we end up with something that looks a bit like:
` packages: - '.' - location: git: https://github.com/jsdw/hs-commander commit: abcdef123456789abcdef1234`
Commanderinto your library.
you can run the example code by running
stack install :example1 && example1 assuming that the directory stack copies binaries to is present in your
if you clone this repository locally somewhere, you can use
stack haddock inside its folder in order to generate haddock documentation for it.
This project is still under heavy development and could well change drastically!