content: -- | This module contains an arrow interface for option parsers, which allows
  -- to define and combine parsers using the arrow notation and arrow
  -- combinators.
  --
  -- The arrow syntax is particularly useful to create parsers of nested
  -- structures, or records where the order of fields is different from the order
  -- in which the parsers should be applied.
  --
  -- For example, an 'Options.Applicative.Builder.arguments` parser often needs
  -- to be applied last, and that makes it inconvenient to use it for a field
  -- which is not the last one in a record.
  --
  -- Using the arrow syntax and the functions in this module, one can write, e.g.:
  --
  -- > data Options = Options
  -- >   { optArgs :: [String]
  -- >   , optVerbose :: Bool }
  -- >
  -- > opts :: Parser Options
  -- > opts = runA $ proc () -> do
  -- >   verbose <- asA (switch (short 'v')) -< ()
  -- >   args <- asA (arguments str idm) -< ()
  -- >   returnA -< Options args verbose
  --
  -- Parser arrows, created out of regular 'Parser' values using the 'asA'
  -- function, are arrows taking @()@ as argument and returning the parsed value.
  module Options.Applicative.Arrows (
    module Control.Arrow,
    A(..),
    asA,
    runA,
    ParserA,
    ) where
  
  import Control.Arrow
  import Control.Category (Category(..))
  
  import Options.Applicative
  
  import Prelude hiding ((.), id)
  
  -- | For any 'Applicative' functor @f@, @A f@ is the 'Arrow' instance
  -- associated to @f@.
  --
  -- The 'A' constructor can be used to convert a value of type @f (a -> b)@ into
  -- an arrow.
  newtype A f a b = A
    { unA :: f (a -> b) }
  
  -- | Convert a value of type @f a@ into an arrow taking @()@ as argument.
  --
  -- Applied to a value of type 'Parser', it turns it into an arrow that can be
  -- used inside an arrow command, or passed to arrow combinators.
  asA :: Applicative f => f a -> A f () a
  asA x = A $ const <$> x
  
  -- | Convert an arrow back to an applicative value.
  --
  -- This function can be used to return a result of type 'Parser' from an arrow
  -- command.
  runA :: Applicative f => A f () a -> f a
  runA a = unA a <*> pure ()
  
  instance Applicative f => Category (A f) where
    id = A $ pure id
    -- use reverse composition, because we want effects to run from
    -- top to bottom in the arrow syntax
    (A f) . (A g) = A $ flip (.) <$> g <*> f
  
  instance Applicative f => Arrow (A f) where
    arr = A . pure
    first (A f) = A $ first <$> f
  
  -- | The type of arrows associated to the applicative 'Parser' functor.
  type ParserA = A Parser
  