Command line arguments reading a monad library

I am looking for a library that uses a monad to abstract over the judgment of arguments of command line arguments and creating help. I have the following pretty obvious usage model:

main = do portOrSocket <- Args.run $ do mbSocket <- Args.read $ Args.Arg "s" "socket" "Description" mbPort <- Args.read $ Args.Arg "p" "port" "Description" case mbSocket of Just socket -> return $ Right socket Nothing -> case mbPort of Just port -> return $ Left port Nothing -> return $ Left defaultPort ... 

The above code contains all the information needed to process parsing, validation and use, and IMO is pretty easy to understand. Unfortunately, after looking at the hack and checking for packages like cmdargs, cmdlib, parseargs, ReadArgs, I did not find anything nearby. But before diving into the implementation, I would like to make sure that I did not miss anything. So, is there a library that uses a similar approach to the problem?

+7
source share
2 answers

You can use optparse-applicative . The most common usage pattern looks like this (I just copy and paste from a small utility that I use):

 options :: Parser (String, String) options = (,) <$> (strOption $ mconcat [ short 'n', long "node", metavar "NODE", value "127.0.0.1", showDefaultWith id, completer (bashCompleter "hostname"), help "AMQP node to connect to" ] ) <*> (strOption $ mconcat [ short 'q', long "queue", metavar "QUEUE", value "1.0.0", showDefaultWith id, help "Queue to initialize" ] ) main = do (hostName, queue) <- execParser $ info (helper <*> options) $ mconcat [ fullDesc, header "The Suns setup utility", progDesc "Sets up an AMQP node", footer "Report bugs to Gabriel439@gmail.com " ] ... 

When I run the compiled program with -h , I get:

 $ suns-admin -h The Suns setup utility Usage: suns-admin [-n|--node NODE] [-q|--queue QUEUE] Sets up an AMQP node Available options: -h,--help Show this help text -n,--node NODE AMQP node to connect to (default: 127.0.0.1) -q,--queue QUEUE Queue to initialize (default: 1.0.0) Report bugs to Gabriel439@gmail.com 

This gives you an idea of ​​some great options you can play with and the good output that the program generates.

+8
source

If someone is interested in solving the problem presented in the question using optparse-applicative , here is how I achieved this:

 import Options.Applicative getOptions :: Int -> IO (Either Int String) getOptions defaultPort = execParser $ info (helper <*> parser defaultPort) $ fullDesc <> progDesc "Run a content-db server on a socket or a port" <> header "Run a content-db server" parser :: Int -> Parser (Either Int String) parser defaultPort = portOrSocket <$> (optional . strOption) ( short 's' <> long "socket" <> help "Socket" ) <*> option ( short 'p' <> long "port" <> help "Port" <> value defaultPort ) where portOrSocket (Just socket) _ = Right socket portOrSocket _ port = Left port main = do getOptions 43400 >>= \o -> case o of Left port -> print port Right socket -> print socket 
+2
source

All Articles