2013-06-30 14 views
7

私は、モナドを使ってコマンドライン引数の解析と生成の騒ぎを抽象化するライブラリを探しています。私は心の中で、次のかなり明白な使用パターンを持っている:モナドライブラリを読むコマンドライン引数

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 
    ... 

上記のコードは、構文解析、検証と使用方法の生成を処理するために必要なすべての情報を持っており、IMOが理解することはかなり簡単です。残念なことに、ハッカーを見てcmdargs、cmdlib、parseargs、ReadArgsのようなパッケージをチェックした後、私はこれに近いところには何も見つかりませんでした。しかし、実装に入る前に、私が何かを見逃さないようにしたいと思います。それで、問題と同様のアプローチを利用するライブラリはありますか?

+8

あなたは 'optparseは-applicative'を試したことがありますか? –

+4

+1は 'optparse-applicative'です。それは素晴らしい。 – jtobin

+1

パラメータが他のパラメータの値に依存する場合、自動ヘルプメッセージを生成することはほとんど不可能であるようです。これはおそらく_optparse-applicative_がApplicativeを使用する理由です。 –

答えて

8

optparse-applicativeを使用できます。最も一般的な使用パターンは、(私はコピー&ペースト、私が使用して小さなユーティリティからだ)次のようになります。

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 [email protected]" ] 
    ... 

私は-hでコンパイルされたプログラムを実行すると、私が手:

$ 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 [email protected] 

これは、あなたが遊ぶことができるすばらしいオプションと、プログラムが生成する素敵な出力のいくつかのアイデアを提供します。

2

誰もがoptparse-applicativeを使用して、問題の提示、問題の解決に興味を持っていた場合は、ここで私がいることを実現方法は次のとおりです。

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 
関連する問題