    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE NamedFieldPuns #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE RecordWildCards #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE StandaloneDeriving #-}

    module WithCli.Parser where

    import           Data.Orphans ()
    import           Prelude ()
    import           Prelude.Compat

    import           Control.Arrow
    import           Control.Monad
    import           System.Console.GetOpt as Base

    import           WithCli.Flag
    import           WithCli.Modifier.Types
    import           WithCli.Normalize
    import           WithCli.Result

    data NonOptionsParser uninitialized =
      NonOptionsParser {
        forall uninitialized. NonOptionsParser uninitialized -> String
    nonOptionsType :: String,
        forall uninitialized. NonOptionsParser uninitialized -> Bool
    nonOptionsOptional :: Bool,
        forall uninitialized.
    NonOptionsParser uninitialized
    -> [String] -> Result (uninitialized -> uninitialized, [String])
    nonOptionsParser ::
          [String] -> Result (uninitialized -> uninitialized, [String])
      }

    combineNonOptionsParser :: [NonOptionsParser u] -> [NonOptionsParser v]
      -> [NonOptionsParser (u, v)]
    combineNonOptionsParser :: forall u v.
    [NonOptionsParser u]
    -> [NonOptionsParser v] -> [NonOptionsParser (u, v)]
    combineNonOptionsParser [NonOptionsParser u]
    a [NonOptionsParser v]
    b =
      (NonOptionsParser u -> NonOptionsParser (u, v))
    -> [NonOptionsParser u] -> [NonOptionsParser (u, v)]
    forall a b. (a -> b) -> [a] -> [b]
    map (((u -> u) -> (u, v) -> (u, v))
    -> NonOptionsParser u -> NonOptionsParser (u, v)
    forall a b.
    ((a -> a) -> b -> b) -> NonOptionsParser a -> NonOptionsParser b
    modMod (u -> u) -> (u, v) -> (u, v)
    forall b c d. (b -> c) -> (b, d) -> (c, d)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    first) [NonOptionsParser u]
    a [NonOptionsParser (u, v)]
    -> [NonOptionsParser (u, v)] -> [NonOptionsParser (u, v)]
    forall a. [a] -> [a] -> [a]
    ++
      (NonOptionsParser v -> NonOptionsParser (u, v))
    -> [NonOptionsParser v] -> [NonOptionsParser (u, v)]
    forall a b. (a -> b) -> [a] -> [b]
    map (((v -> v) -> (u, v) -> (u, v))
    -> NonOptionsParser v -> NonOptionsParser (u, v)
    forall a b.
    ((a -> a) -> b -> b) -> NonOptionsParser a -> NonOptionsParser b
    modMod (v -> v) -> (u, v) -> (u, v)
    forall b c d. (b -> c) -> (d, b) -> (d, c)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (d, b) (d, c)
    second) [NonOptionsParser v]
    b
      where
        modMod :: ((a -> a) -> (b -> b)) -> NonOptionsParser a -> NonOptionsParser b
        modMod :: forall a b.
    ((a -> a) -> b -> b) -> NonOptionsParser a -> NonOptionsParser b
    modMod (a -> a) -> b -> b
    f (NonOptionsParser String
    field Bool
    optional [String] -> Result (a -> a, [String])
    parser) =
          String
    -> Bool
    -> ([String] -> Result (b -> b, [String]))
    -> NonOptionsParser b
    forall uninitialized.
    String
    -> Bool
    -> ([String] -> Result (uninitialized -> uninitialized, [String]))
    -> NonOptionsParser uninitialized
    NonOptionsParser String
    field Bool
    optional ((Result (a -> a, [String]) -> Result (b -> b, [String]))
    -> ([String] -> Result (a -> a, [String]))
    -> [String]
    -> Result (b -> b, [String])
    forall a b. (a -> b) -> ([String] -> a) -> [String] -> b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (((a -> a, [String]) -> (b -> b, [String]))
    -> Result (a -> a, [String]) -> Result (b -> b, [String])
    forall a b. (a -> b) -> Result a -> Result b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (((a -> a) -> b -> b) -> (a -> a, [String]) -> (b -> b, [String])
    forall b c d. (b -> c) -> (b, d) -> (c, d)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    first (a -> a) -> b -> b
    f)) [String] -> Result (a -> a, [String])
    parser)

    data Parser phase a where
      Parser :: {
        ()
    parserDefault :: uninitialized,
        ()
    parserOptions :: [OptDescr (Result (uninitialized -> uninitialized))],
        ()
    parserNonOptions :: [NonOptionsParser uninitialized],
        ()
    parserConvert :: uninitialized -> Result a
      } -> Parser phase a

    instance Functor (Parser phase) where
      fmap :: forall a b. (a -> b) -> Parser phase a -> Parser phase b
    fmap a -> b
    f (Parser uninitialized
    def [OptDescr (Result (uninitialized -> uninitialized))]
    options [NonOptionsParser uninitialized]
    nonOptions uninitialized -> Result a
    convert) =
        uninitialized
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    -> [NonOptionsParser uninitialized]
    -> (uninitialized -> Result b)
    -> Parser phase b
    forall uninitialized a phase.
    uninitialized
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    -> [NonOptionsParser uninitialized]
    -> (uninitialized -> Result a)
    -> Parser phase a
    Parser uninitialized
    def [OptDescr (Result (uninitialized -> uninitialized))]
    options [NonOptionsParser uninitialized]
    nonOptions ((a -> b) -> Result a -> Result b
    forall a b. (a -> b) -> Result a -> Result b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f (Result a -> Result b)
    -> (uninitialized -> Result a) -> uninitialized -> Result b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . uninitialized -> Result a
    convert)

    -- phases:
    data Unnormalized
    data Normalized

    emptyParser :: a -> Parser phase a
    emptyParser :: forall a phase. a -> Parser phase a
    emptyParser a
    a = Parser {
      parserDefault :: a
    parserDefault = a
    a,
      parserOptions :: [OptDescr (Result (a -> a))]
    parserOptions = [],
      parserNonOptions :: [NonOptionsParser a]
    parserNonOptions = [],
      parserConvert :: a -> Result a
    parserConvert = a -> Result a
    forall a. a -> Result a
    forall (m :: * -> *) a. Monad m => a -> m a
    return
    }

    normalizeParser :: Parser Unnormalized a -> Parser Normalized a
    normalizeParser :: forall a. Parser Unnormalized a -> Parser Normalized a
    normalizeParser (Parser uninitialized
    d [OptDescr (Result (uninitialized -> uninitialized))]
    options [NonOptionsParser uninitialized]
    nonOptions uninitialized -> Result a
    convert) =
      uninitialized
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    -> [NonOptionsParser uninitialized]
    -> (uninitialized -> Result a)
    -> Parser Normalized a
    forall uninitialized a phase.
    uninitialized
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    -> [NonOptionsParser uninitialized]
    -> (uninitialized -> Result a)
    -> Parser phase a
    Parser uninitialized
    d ((OptDescr (Result (uninitialized -> uninitialized))
     -> OptDescr (Result (uninitialized -> uninitialized)))
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    forall a b. (a -> b) -> [a] -> [b]
    map ((String -> String)
    -> OptDescr (Result (uninitialized -> uninitialized))
    -> OptDescr (Result (uninitialized -> uninitialized))
    forall a. (String -> String) -> OptDescr a -> OptDescr a
    mapLongOptions String -> String
    normalize) [OptDescr (Result (uninitialized -> uninitialized))]
    options) [NonOptionsParser uninitialized]
    nonOptions uninitialized -> Result a
    convert
      where
        mapLongOptions :: (String -> String) -> OptDescr a -> OptDescr a
        mapLongOptions :: forall a. (String -> String) -> OptDescr a -> OptDescr a
    mapLongOptions String -> String
    f (Option String
    shorts [String]
    longs ArgDescr a
    argDescr String
    help) =
          String -> [String] -> ArgDescr a -> String -> OptDescr a
    forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
    Option String
    shorts ((String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> String
    f [String]
    longs) ArgDescr a
    argDescr String
    help

    modParserOptions :: (forall x . [OptDescr (Result x)] -> [OptDescr (Result x)])
      -> Parser Unnormalized a -> Parser Unnormalized a
    modParserOptions :: forall a.
    (forall x. [OptDescr (Result x)] -> [OptDescr (Result x)])
    -> Parser Unnormalized a -> Parser Unnormalized a
    modParserOptions forall x. [OptDescr (Result x)] -> [OptDescr (Result x)]
    f (Parser uninitialized
    def [OptDescr (Result (uninitialized -> uninitialized))]
    options [NonOptionsParser uninitialized]
    nonOptions uninitialized -> Result a
    convert) =
      uninitialized
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    -> [NonOptionsParser uninitialized]
    -> (uninitialized -> Result a)
    -> Parser Unnormalized a
    forall uninitialized a phase.
    uninitialized
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    -> [NonOptionsParser uninitialized]
    -> (uninitialized -> Result a)
    -> Parser phase a
    Parser uninitialized
    def ([OptDescr (Result (uninitialized -> uninitialized))]
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    forall x. [OptDescr (Result x)] -> [OptDescr (Result x)]
    f [OptDescr (Result (uninitialized -> uninitialized))]
    options) [NonOptionsParser uninitialized]
    nonOptions uninitialized -> Result a
    convert

    combine :: forall a b phase .
      Result (Parser phase a) -> Result (Parser phase b)
      -> Result (Parser phase (a, b))
    combine :: forall a b phase.
    Result (Parser phase a)
    -> Result (Parser phase b) -> Result (Parser phase (a, b))
    combine Result (Parser phase a)
    a Result (Parser phase b)
    b = Parser phase a -> Parser phase b -> Parser phase (a, b)
    inner (Parser phase a -> Parser phase b -> Parser phase (a, b))
    -> Result (Parser phase a)
    -> Result (Parser phase b -> Parser phase (a, b))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Result (Parser phase a)
    a Result (Parser phase b -> Parser phase (a, b))
    -> Result (Parser phase b) -> Result (Parser phase (a, b))
    forall a b. Result (a -> b) -> Result a -> Result b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Result (Parser phase b)
    b
      where
        inner :: Parser phase a -> Parser phase b -> Parser phase (a, b)
        inner :: Parser phase a -> Parser phase b -> Parser phase (a, b)
    inner (Parser uninitialized
    defaultA [OptDescr (Result (uninitialized -> uninitialized))]
    optionsA [NonOptionsParser uninitialized]
    nonOptionsA uninitialized -> Result a
    convertA) (Parser uninitialized
    defaultB [OptDescr (Result (uninitialized -> uninitialized))]
    optionsB [NonOptionsParser uninitialized]
    nonOptionsB uninitialized -> Result b
    convertB) =
          Parser {
            parserDefault :: (uninitialized, uninitialized)
    parserDefault = (uninitialized
    defaultA, uninitialized
    defaultB),
            parserOptions :: [OptDescr
       (Result
          ((uninitialized, uninitialized)
           -> (uninitialized, uninitialized)))]
    parserOptions =
              (OptDescr (Result (uninitialized -> uninitialized))
     -> OptDescr
          (Result
             ((uninitialized, uninitialized)
              -> (uninitialized, uninitialized))))
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    -> [OptDescr
          (Result
             ((uninitialized, uninitialized)
              -> (uninitialized, uninitialized)))]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Result (uninitialized -> uninitialized)
     -> Result
          ((uninitialized, uninitialized) -> (uninitialized, uninitialized)))
    -> OptDescr (Result (uninitialized -> uninitialized))
    -> OptDescr
         (Result
            ((uninitialized, uninitialized) -> (uninitialized, uninitialized)))
    forall a b. (a -> b) -> OptDescr a -> OptDescr b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (((uninitialized -> uninitialized)
     -> (uninitialized, uninitialized)
     -> (uninitialized, uninitialized))
    -> Result (uninitialized -> uninitialized)
    -> Result
         ((uninitialized, uninitialized) -> (uninitialized, uninitialized))
    forall a b. (a -> b) -> Result a -> Result b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (uninitialized -> uninitialized)
    -> (uninitialized, uninitialized) -> (uninitialized, uninitialized)
    forall b c d. (b -> c) -> (b, d) -> (c, d)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    first)) [OptDescr (Result (uninitialized -> uninitialized))]
    optionsA [OptDescr
       (Result
          ((uninitialized, uninitialized)
           -> (uninitialized, uninitialized)))]
    -> [OptDescr
          (Result
             ((uninitialized, uninitialized)
              -> (uninitialized, uninitialized)))]
    -> [OptDescr
          (Result
             ((uninitialized, uninitialized)
              -> (uninitialized, uninitialized)))]
    forall a. [a] -> [a] -> [a]
    ++ (OptDescr (Result (uninitialized -> uninitialized))
     -> OptDescr
          (Result
             ((uninitialized, uninitialized)
              -> (uninitialized, uninitialized))))
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    -> [OptDescr
          (Result
             ((uninitialized, uninitialized)
              -> (uninitialized, uninitialized)))]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Result (uninitialized -> uninitialized)
     -> Result
          ((uninitialized, uninitialized) -> (uninitialized, uninitialized)))
    -> OptDescr (Result (uninitialized -> uninitialized))
    -> OptDescr
         (Result
            ((uninitialized, uninitialized) -> (uninitialized, uninitialized)))
    forall a b. (a -> b) -> OptDescr a -> OptDescr b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (((uninitialized -> uninitialized)
     -> (uninitialized, uninitialized)
     -> (uninitialized, uninitialized))
    -> Result (uninitialized -> uninitialized)
    -> Result
         ((uninitialized, uninitialized) -> (uninitialized, uninitialized))
    forall a b. (a -> b) -> Result a -> Result b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (uninitialized -> uninitialized)
    -> (uninitialized, uninitialized) -> (uninitialized, uninitialized)
    forall b c d. (b -> c) -> (d, b) -> (d, c)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (d, b) (d, c)
    second)) [OptDescr (Result (uninitialized -> uninitialized))]
    optionsB,
            parserNonOptions :: [NonOptionsParser (uninitialized, uninitialized)]
    parserNonOptions = [NonOptionsParser uninitialized]
    -> [NonOptionsParser uninitialized]
    -> [NonOptionsParser (uninitialized, uninitialized)]
    forall u v.
    [NonOptionsParser u]
    -> [NonOptionsParser v] -> [NonOptionsParser (u, v)]
    combineNonOptionsParser [NonOptionsParser uninitialized]
    nonOptionsA [NonOptionsParser uninitialized]
    nonOptionsB,
            parserConvert :: (uninitialized, uninitialized) -> Result (a, b)
    parserConvert =
              \ (uninitialized
    u, uninitialized
    v) -> (,) (a -> b -> (a, b)) -> Result a -> Result (b -> (a, b))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (uninitialized -> Result a
    convertA uninitialized
    u) Result (b -> (a, b)) -> Result b -> Result (a, b)
    forall a b. Result (a -> b) -> Result a -> Result b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> (uninitialized -> Result b
    convertB uninitialized
    v)
          }

    fillInOptions :: [Result (u -> u)] -> u -> Result u
    fillInOptions :: forall u. [Result (u -> u)] -> u -> Result u
    fillInOptions [] u
    u = u -> Result u
    forall a. a -> Result a
    forall (m :: * -> *) a. Monad m => a -> m a
    return u
    u
    fillInOptions (Result (u -> u)
    option : [Result (u -> u)]
    options) u
    u = do
      f <- Result (u -> u)
    option
      fillInOptions options (f u)

    fillInNonOptions :: [[String] -> Result (u -> u, [String])] -> [String] -> u
      -> Result u
    fillInNonOptions :: forall u.
    [[String] -> Result (u -> u, [String])]
    -> [String] -> u -> Result u
    fillInNonOptions ([String] -> Result (u -> u, [String])
    parser : [[String] -> Result (u -> u, [String])]
    parsers) nonOptions :: [String]
    nonOptions@(String
    _ : [String]
    _) u
    u = do
      (p, rest) <- [String] -> Result (u -> u, [String])
    parser [String]
    nonOptions
      fillInNonOptions parsers rest (p u)
    fillInNonOptions [] [] u
    u =
      u -> Result u
    forall a. a -> Result a
    forall (m :: * -> *) a. Monad m => a -> m a
    return u
    u
    fillInNonOptions [] [String]
    nonOptions u
    _ =
      String -> Result u
    forall a. String -> Result a
    Errors (String -> Result u) -> String -> Result u
    forall a b. (a -> b) -> a -> b
    $ [String] -> String
    unlines ((String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String
    "unknown argument: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++) [String]
    nonOptions)
    fillInNonOptions [[String] -> Result (u -> u, [String])]
    _ [] u
    u = u -> Result u
    forall a. a -> Result a
    forall (m :: * -> *) a. Monad m => a -> m a
    return u
    u

    runParser :: String -> Modifiers -> Parser Normalized a -> [String] -> Result a
    runParser :: forall a.
    String -> Modifiers -> Parser Normalized a -> [String] -> Result a
    runParser String
    progName Modifiers
    modifiers Parser{uninitialized
    [OptDescr (Result (uninitialized -> uninitialized))]
    [NonOptionsParser uninitialized]
    uninitialized -> Result a
    parserDefault :: ()
    parserOptions :: ()
    parserNonOptions :: ()
    parserConvert :: ()
    parserDefault :: uninitialized
    parserOptions :: [OptDescr (Result (uninitialized -> uninitialized))]
    parserNonOptions :: [NonOptionsParser uninitialized]
    parserConvert :: uninitialized -> Result a
    ..} [String]
    args =
      [NonOptionsParser uninitialized] -> Result ()
    forall a. [NonOptionsParser a] -> Result ()
    checkNonOptionParsers [NonOptionsParser uninitialized]
    parserNonOptions Result () -> Result a -> Result a
    forall a b. Result a -> Result b -> Result b
    |>
      let versionOptions :: [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    versionOptions = [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    -> (String
        -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))])
    -> Maybe String
    -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe []
            (\ String
    v -> OptDescr (Flag (Result (uninitialized -> uninitialized)))
    -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    forall a. a -> [a]
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (OptDescr (Flag (Result (uninitialized -> uninitialized)))
     -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))])
    -> OptDescr (Flag (Result (uninitialized -> uninitialized)))
    -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    forall a b. (a -> b) -> a -> b
    $ String -> OptDescr (Flag (Result (uninitialized -> uninitialized)))
    forall a. String -> OptDescr (Flag a)
    versionOption (String
    progName String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    " version " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    v))
            (Modifiers -> Maybe String
    getVersion Modifiers
    modifiers)
          options :: [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    options = (OptDescr (Result (uninitialized -> uninitialized))
     -> OptDescr (Flag (Result (uninitialized -> uninitialized))))
    -> [OptDescr (Result (uninitialized -> uninitialized))]
    -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Result (uninitialized -> uninitialized)
     -> Flag (Result (uninitialized -> uninitialized)))
    -> OptDescr (Result (uninitialized -> uninitialized))
    -> OptDescr (Flag (Result (uninitialized -> uninitialized)))
    forall a b. (a -> b) -> OptDescr a -> OptDescr b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Result (uninitialized -> uninitialized)
    -> Flag (Result (uninitialized -> uninitialized))
    forall a. a -> Flag a
    NoHelp) [OptDescr (Result (uninitialized -> uninitialized))]
    parserOptions [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    forall a. [a] -> [a] -> [a]
    ++ [OptDescr (Flag (Result (uninitialized -> uninitialized)))
    forall a. OptDescr (Flag a)
    helpOption] [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    forall a. [a] -> [a] -> [a]
    ++ [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    versionOptions
          ([Flag (Result (uninitialized -> uninitialized))]
    flags, [String]
    nonOptions, [String]
    errs) =
            ArgOrder (Flag (Result (uninitialized -> uninitialized)))
    -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    -> [String]
    -> ([Flag (Result (uninitialized -> uninitialized))], [String],
        [String])
    forall a.
    ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String])
    Base.getOpt ArgOrder (Flag (Result (uninitialized -> uninitialized)))
    forall a. ArgOrder a
    Base.Permute [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    options [String]
    args
      in case [Flag (Result (uninitialized -> uninitialized))]
    -> Flag [Result (uninitialized -> uninitialized)]
    forall a. [Flag a] -> Flag [a]
    foldFlags [Flag (Result (uninitialized -> uninitialized))]
    flags of
        Flag [Result (uninitialized -> uninitialized)]
    Help -> String -> Result a
    forall a. String -> Result a
    OutputAndExit (String -> Result a) -> String -> Result a
    forall a b. (a -> b) -> a -> b
    $
          let fields :: [(Bool, String)]
    fields = case Modifiers -> Maybe String
    getPositionalArgumentType Modifiers
    modifiers of
                Maybe String
    Nothing -> (NonOptionsParser uninitialized -> (Bool, String))
    -> [NonOptionsParser uninitialized] -> [(Bool, String)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\ NonOptionsParser uninitialized
    p -> (NonOptionsParser uninitialized -> Bool
    forall uninitialized. NonOptionsParser uninitialized -> Bool
    nonOptionsOptional NonOptionsParser uninitialized
    p, NonOptionsParser uninitialized -> String
    forall uninitialized. NonOptionsParser uninitialized -> String
    nonOptionsType NonOptionsParser uninitialized
    p)) [NonOptionsParser uninitialized]
    parserNonOptions
                Just String
    typ -> [(Bool
    True, String
    typ)]
          in String -> [(Bool, String)] -> [OptDescr ()] -> String
    usage String
    progName [(Bool, String)]
    fields ((OptDescr (Flag (Result (uninitialized -> uninitialized)))
     -> OptDescr ())
    -> [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    -> [OptDescr ()]
    forall a b. (a -> b) -> [a] -> [b]
    map OptDescr (Flag (Result (uninitialized -> uninitialized)))
    -> OptDescr ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void [OptDescr (Flag (Result (uninitialized -> uninitialized)))]
    options)
        Version String
    msg -> String -> Result a
    forall a. String -> Result a
    OutputAndExit String
    msg
        NoHelp [Result (uninitialized -> uninitialized)]
    innerFlags ->
          [String] -> Result ()
    reportErrors [String]
    errs Result () -> Result a -> Result a
    forall a b. Result a -> Result b -> Result b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *>
          ([Result (uninitialized -> uninitialized)]
    -> uninitialized -> Result uninitialized
    forall u. [Result (u -> u)] -> u -> Result u
    fillInOptions [Result (uninitialized -> uninitialized)]
    innerFlags uninitialized
    parserDefault Result uninitialized
    -> (uninitialized -> Result uninitialized) -> Result uninitialized
    forall a b. Result a -> (a -> Result b) -> Result b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>=
           [[String] -> Result (uninitialized -> uninitialized, [String])]
    -> [String] -> uninitialized -> Result uninitialized
    forall u.
    [[String] -> Result (u -> u, [String])]
    -> [String] -> u -> Result u
    fillInNonOptions ((NonOptionsParser uninitialized
     -> [String] -> Result (uninitialized -> uninitialized, [String]))
    -> [NonOptionsParser uninitialized]
    -> [[String] -> Result (uninitialized -> uninitialized, [String])]
    forall a b. (a -> b) -> [a] -> [b]
    map NonOptionsParser uninitialized
    -> [String] -> Result (uninitialized -> uninitialized, [String])
    forall uninitialized.
    NonOptionsParser uninitialized
    -> [String] -> Result (uninitialized -> uninitialized, [String])
    nonOptionsParser [NonOptionsParser uninitialized]
    parserNonOptions) [String]
    nonOptions Result uninitialized -> (uninitialized -> Result a) -> Result a
    forall a b. Result a -> (a -> Result b) -> Result b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>=
           uninitialized -> Result a
    parserConvert)
      where
        reportErrors :: [String] -> Result ()
        reportErrors :: [String] -> Result ()
    reportErrors = \ case
          [] -> () -> Result ()
    forall a. a -> Result a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          [String]
    errs -> String -> Result ()
    forall a. String -> Result a
    Errors (String -> Result ()) -> String -> Result ()
    forall a b. (a -> b) -> a -> b
    $ [String] -> String
    unlines [String]
    errs

        checkNonOptionParsers :: [NonOptionsParser a] -> Result ()
        checkNonOptionParsers :: forall a. [NonOptionsParser a] -> Result ()
    checkNonOptionParsers [NonOptionsParser a]
    parsers =
          case (NonOptionsParser a -> Bool)
    -> [NonOptionsParser a] -> [NonOptionsParser a]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile NonOptionsParser a -> Bool
    forall uninitialized. NonOptionsParser uninitialized -> Bool
    nonOptionsOptional ([NonOptionsParser a] -> [NonOptionsParser a])
    -> [NonOptionsParser a] -> [NonOptionsParser a]
    forall a b. (a -> b) -> a -> b
    $ (NonOptionsParser a -> Bool)
    -> [NonOptionsParser a] -> [NonOptionsParser a]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile (Bool -> Bool
    not (Bool -> Bool)
    -> (NonOptionsParser a -> Bool) -> NonOptionsParser a -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NonOptionsParser a -> Bool
    forall uninitialized. NonOptionsParser uninitialized -> Bool
    nonOptionsOptional) [NonOptionsParser a]
    parsers of
            [] -> () -> Result ()
    forall a. a -> Result a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
            (NonOptionsParser a
    _ : [NonOptionsParser a]
    _) -> String -> Result ()
    forall a. String -> Result a
    Errors String
    "cannot use Maybes for optional arguments before any non-optional arguments"