Подтвердить что ты не робот

Как разбираться Может быть, с optparse-applyative

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

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

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

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

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

Ответ 1

См. следующий отрывок optparse-applicative README:

Парсеры являются экземплярами как Applicative, так и Alternative, и работают с любым общим комбинатором, например many и some. Например, чтобы сделать опция return 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}