12

Я пытаюсь использовать optparse-applicative, чтобы разобрать Maybe String, но я не могу найти нигде, как бороться с Maybe. Единственное, что я нашел, это добавить значение по умолчанию, но мне действительно нужен Nothing, если пользователь не предоставил опцию вместо "". Есть ли способ достичь этого?Как разобрать Может быть с optparse-applyative

Вот пример рабочего кода:

import Options.Applicative 

data Config = Config 
    { cIn :: String 
    , cOut :: String 
    } deriving Show 

configParser :: Parser Config 
configParser = Config 
    <$> strOption (long "in" <> short 'i') 
    <*> strOption (long "out" <> short 'o') 


main :: IO() 
main = do 
    conf <- execParser (info configParser fullDesc) 
    print conf 

Однако, я хотел бы параметры быть факультативным и использовать Maybe String вместо String в Config:

data Config = Config 
    { cIn :: Maybe String 
    , cOut :: Maybe String 
    } deriving Show 
+1

Я не знаю 'optparse-applyative', но [эта страница] (https://hackage.haskell.org/package/optparse-applicative-0.11.0.2) предполагает, что применение комбинатора' optional' поверх 'strOption' должен делать то, что вы хотите. – Jubobs

+0

Я не видел, чтобы в нижней части страницы находился дополнительный документ. Это работает. Можете ли вы опубликовать его в качестве ответа, и я приму его. – mb14

ответ

16

Смотрите следующий проход optparse-applicative README:

Parsers находятся в позиции как Applicative, так и Alternative, а также работа с любым общим комбинатором, например many и some. Например, чтобы сделать вариант возврата Nothing вместо неудачу, когда это не входит в комплект, вы можете использовать optional комбинатор в Control.Applicative:

optional $ strOption 
    (long "output" 
    <> metavar "DIRECTORY") 

Соответственно, все, что вам нужно сделать, это применить optional комбинатор к результат strOption:

import Options.Applicative 

data Config = Config 
    { cIn :: Maybe String 
    , cOut :: Maybe String 
    } deriving Show 

configParser :: Parser Config 
configParser = Config 
    <$> (optional $ strOption $ long "in" <> short 'i') 
    <*> (optional $ strOption $ long "out" <> short 'o') 

main :: IO() 
main = do 
    conf <- execParser (info configParser fullDesc) 
    print conf 

тесты в командной строке:

$ main --in foo -o bar 
Config {cIn = Just "foo", cOut = Just "bar"} 
$ main -i foo 
Config {cIn = Just "foo", cOut = Nothing} 
Смежные вопросы