optparse-applicative 0.1.0 → 0.1.1
raw patch · 5 files changed
+117/−3 lines, 5 filesdep ~optparse-applicativePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: optparse-applicative
API changes (from Hackage documentation)
+ Options.Applicative.Arrows: A :: f (a -> b) -> A f a b
+ Options.Applicative.Arrows: asA :: Applicative f => f a -> A f () a
+ Options.Applicative.Arrows: instance Applicative f => Arrow (A f)
+ Options.Applicative.Arrows: instance Applicative f => Category (A f)
+ Options.Applicative.Arrows: newtype A f a b
+ Options.Applicative.Arrows: runA :: Applicative f => A f () a -> f a
+ Options.Applicative.Arrows: type ParserA = A Parser
+ Options.Applicative.Arrows: unA :: A f a b -> f (a -> b)
Files
- Options/Applicative/Arrows.hs +74/−0
- Options/Applicative/Builder.hs +1/−1
- README.md +28/−0
- optparse-applicative.cabal +3/−2
- tests/Tests.hs +11/−0
+ Options/Applicative/Arrows.hs view
@@ -0,0 +1,74 @@+-- | 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+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
Options/Applicative/Builder.hs view
@@ -171,7 +171,7 @@ multi :: Mod f r a [a] multi = optionMod f where- f opt = mkOptGroup []+ f opt = optCont ^%= (fmap (fmap reverse) . ) $ mkOptGroup [] where mkOptGroup xs = opt { _optDefault = Just xs
README.md view
@@ -264,6 +264,33 @@ See the haddock documentation for `Options.Applicative.Builder` for a full list of builders and modifiers. +# Arrow interface++It is also possible to use the [Arrow syntax][arrows] to combine basic parsers.++This can be particularly useful when the structure holding parse results is+deeply nested, or when the order of fields differs from the order in which the+parsers should be applied.++Using functions from the `Options.Applicative.Arrows` module, one can write,+for example:++```haskell+data Options = Options+ { optArgs :: [String]+ , optVerbose :: Bool }++opts :: Parser Options+opts = runA $ proc () -> do+ verbosity <- asA (option (short 'v' & value 0)) -< ()+ let verbose = verbosity > 0+ args <- asA (arguments str idm) -< ()+ returnA -< Options args verbose+```++where parsers can be converted to arrows using `asA`, and the resulting+composed arrow is converted back to a `Parser` with `runA`.+ ## How it works A `Parser a` is essentially a heterogeneous list of `Option`s, implemented with@@ -279,3 +306,4 @@ [status-png]: https://secure.travis-ci.org/pcapriotti/optparse-applicative.png?branch=master [status]: http://travis-ci.org/pcapriotti/optparse-applicative?branch=master [blog]: http://paolocapriotti.com/blog/2012/04/27/applicative-option-parser/+ [arrows]: http://www.haskell.org/arrows/syntax.html
optparse-applicative.cabal view
@@ -1,5 +1,5 @@ name: optparse-applicative-version: 0.1.0+version: 0.1.1 synopsis: Utilities and combinators for parsing command line options description: Here is a simple example of an applicative option parser:@@ -73,6 +73,7 @@ library exposed-modules: Options.Applicative,+ Options.Applicative.Arrows, Options.Applicative.Common, Options.Applicative.Types, Options.Applicative.Builder,@@ -89,7 +90,7 @@ main-is: Tests.hs build-depends: base == 4.*, HUnit == 1.2.*,- optparse-applicative == 0.1.*,+ optparse-applicative == 0.2.*, test-framework == 0.6.*, test-framework-hunit == 0.2.*, test-framework-th-prime == 0.0.*
tests/Tests.hs view
@@ -34,5 +34,16 @@ case_cabal :: Assertion case_cabal = checkHelpText "cabal" Cabal.pinfo ["configure", "--help"] +case_args :: Assertion+case_args = do+ let result = execParserPure Commands.opts ["hello", "foo", "bar"]+ case result of+ Left _ ->+ assertFailure "unexpected parse error"+ Right (Commands.Hello args) ->+ ["foo", "bar"] @=? args+ Right Commands.Goodbye ->+ assertFailure "unexpected result: Goodbye"+ main :: IO () main = $(defaultMainGenerator)