packages feed

descriptive 0.6.0 → 0.7.0

raw patch · 9 files changed

+106/−76 lines, 9 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Descriptive: instance Alternative (Consumer s d)
- Descriptive: instance Applicative (Consumer s d)
- Descriptive: instance Functor (Consumer s d)
- Descriptive: instance Monoid a => Monoid (Consumer s d a)
+ Descriptive: instance (Monoid a, Monad m) => Monoid (Consumer s d m a)
+ Descriptive: instance Monad m => Alternative (Consumer s d m)
+ Descriptive: instance Monad m => Applicative (Consumer s d m)
+ Descriptive: instance Monad m => Functor (Consumer s d m)
- Descriptive: Consumer :: (forall m. Monad m => StateT s m (Description d)) -> (forall m. Monad m => StateT s m (Result (Description d) a)) -> Consumer s d a
+ Descriptive: Consumer :: StateT s m (Description d) -> StateT s m (Result (Description d) a) -> Consumer s d m a
- Descriptive: consume :: Consumer s d a -> s -> Result (Description d) a
+ Descriptive: consume :: Consumer s d Identity a -> s -> Result (Description d) a
- Descriptive: consumer :: (forall m. Monad m => StateT s m (Description d)) -> (forall m. Monad m => StateT s m (Result (Description d) a)) -> Consumer s d a
+ Descriptive: consumer :: (StateT s m (Description d)) -> (StateT s m (Result (Description d) a)) -> Consumer s d m a
- Descriptive: consumerDesc :: Consumer s d a -> forall m. Monad m => StateT s m (Description d)
+ Descriptive: consumerDesc :: Consumer s d m a -> StateT s m (Description d)
- Descriptive: consumerParse :: Consumer s d a -> forall m. Monad m => StateT s m (Result (Description d) a)
+ Descriptive: consumerParse :: Consumer s d m a -> StateT s m (Result (Description d) a)
- Descriptive: data Consumer s d a
+ Descriptive: data Consumer s d m a
- Descriptive: describe :: Consumer s d a -> s -> Description d
+ Descriptive: describe :: Consumer s d Identity a -> s -> Description d
- Descriptive: runConsumer :: Monad m => Consumer s d a -> StateT s m (Result (Description d) a)
+ Descriptive: runConsumer :: Monad m => Consumer s d m a -> StateT s m (Result (Description d) a)
- Descriptive: runDescription :: Monad m => Consumer s d a -> StateT s m (Description d)
+ Descriptive: runDescription :: Monad m => Consumer s d m a -> StateT s m (Description d)
- Descriptive: validate :: d -> (forall m. MonadState s m => a -> m (Maybe b)) -> Consumer s d a -> Consumer s d b
+ Descriptive: validate :: Monad m => d -> (a -> StateT s m (Maybe b)) -> Consumer s d m a -> Consumer s d m b
- Descriptive: wrap :: (forall m. Monad m => StateT t m (Description d) -> StateT s m (Description d)) -> (forall m. Monad m => StateT t m (Description d) -> StateT t m (Result (Description d) a) -> StateT s m (Result (Description d) b)) -> Consumer t d a -> Consumer s d b
+ Descriptive: wrap :: (StateT t m (Description d) -> StateT s m (Description d)) -> (StateT t m (Description d) -> StateT t m (Result (Description d) a) -> StateT s m (Result (Description d) b)) -> Consumer t d m a -> Consumer s d m b
- Descriptive.Char: anyChar :: Consumer [Char] Text Char
+ Descriptive.Char: anyChar :: Monad m => Consumer [Char] Text m Char
- Descriptive.Char: char :: Char -> Consumer [Char] Text Char
+ Descriptive.Char: char :: Monad m => Char -> Consumer [Char] Text m Char
- Descriptive.Char: string :: [Char] -> Consumer [Char] Text [Char]
+ Descriptive.Char: string :: Monad m => [Char] -> Consumer [Char] Text m [Char]
- Descriptive.Form: input :: Text -> Consumer (Map Text Text) Form Text
+ Descriptive.Form: input :: Monad m => Text -> Consumer (Map Text Text) Form m Text
- Descriptive.Formlet: indexed :: Consumer FormletState Formlet Text
+ Descriptive.Formlet: indexed :: Monad m => Consumer FormletState Formlet m Text
- Descriptive.JSON: array :: Text -> Consumer Value Doc a -> Consumer Value Doc (Vector a)
+ Descriptive.JSON: array :: Monad m => Text -> Consumer Value Doc m a -> Consumer Value Doc m (Vector a)
- Descriptive.JSON: bool :: Text -> Consumer Value Doc Bool
+ Descriptive.JSON: bool :: Monad m => Text -> Consumer Value Doc m Bool
- Descriptive.JSON: double :: Text -> Consumer Value Doc Double
+ Descriptive.JSON: double :: Monad m => Text -> Consumer Value Doc m Double
- Descriptive.JSON: info :: Text -> Consumer s Doc a -> Consumer s Doc a
+ Descriptive.JSON: info :: Monad m => Text -> Consumer s Doc m a -> Consumer s Doc m a
- Descriptive.JSON: integer :: Text -> Consumer Value Doc Integer
+ Descriptive.JSON: integer :: Monad m => Text -> Consumer Value Doc m Integer
- Descriptive.JSON: key :: Text -> Consumer Value Doc a -> Consumer Object Doc a
+ Descriptive.JSON: key :: Monad m => Text -> Consumer Value Doc m a -> Consumer Object Doc m a
- Descriptive.JSON: keyMaybe :: Text -> Consumer Value Doc a -> Consumer Object Doc (Maybe a)
+ Descriptive.JSON: keyMaybe :: Monad m => Text -> Consumer Value Doc m a -> Consumer Object Doc m (Maybe a)
- Descriptive.JSON: label :: Text -> Consumer s Doc a -> Consumer s Doc a
+ Descriptive.JSON: label :: Monad m => Text -> Consumer s Doc m a -> Consumer s Doc m a
- Descriptive.JSON: null :: Text -> Consumer Value Doc ()
+ Descriptive.JSON: null :: Monad m => Text -> Consumer Value Doc m ()
- Descriptive.JSON: object :: Text -> Consumer Object Doc a -> Consumer Value Doc a
+ Descriptive.JSON: object :: Monad m => Text -> Consumer Object Doc m a -> Consumer Value Doc m a
- Descriptive.JSON: string :: Text -> Consumer Value Doc Text
+ Descriptive.JSON: string :: Monad m => Text -> Consumer Value Doc m Text
- Descriptive.Options: anyString :: Text -> Consumer [Text] (Option a) Text
+ Descriptive.Options: anyString :: Monad m => Text -> Consumer [Text] (Option a) m Text
- Descriptive.Options: arg :: Text -> Text -> Consumer [Text] (Option a) Text
+ Descriptive.Options: arg :: Monad m => Text -> Text -> Consumer [Text] (Option a) m Text
- Descriptive.Options: constant :: Text -> Text -> v -> Consumer [Text] (Option a) v
+ Descriptive.Options: constant :: Monad m => Text -> Text -> v -> Consumer [Text] (Option a) m v
- Descriptive.Options: flag :: Text -> Text -> v -> Consumer [Text] (Option a) v
+ Descriptive.Options: flag :: Monad m => Text -> Text -> v -> Consumer [Text] (Option a) m v
- Descriptive.Options: prefix :: Text -> Text -> Consumer [Text] (Option a) Text
+ Descriptive.Options: prefix :: Monad m => Text -> Text -> Consumer [Text] (Option a) m Text
- Descriptive.Options: stop :: Consumer [Text] (Option a) a -> Consumer [Text] (Option a) ()
+ Descriptive.Options: stop :: Monad m => Consumer [Text] (Option a) m a -> Consumer [Text] (Option a) m ()
- Descriptive.Options: switch :: Text -> Text -> Consumer [Text] (Option a) Bool
+ Descriptive.Options: switch :: Monad m => Text -> Text -> Consumer [Text] (Option a) m Bool

Files

README.md view
@@ -20,7 +20,7 @@ data Consumer s d a ``` -## Making descriptive consumers+### Making descriptive consumers  To make a consumer, this combinator is used: @@ -39,7 +39,7 @@ strings, a Map, a Vector, etc. You may or may not decide to modify the state during generation of the description and during parsing. -## Running descriptive consumers+### Running descriptive consumers  To use a consumer or describe what it does, these are used: @@ -68,7 +68,7 @@ runDescription (Consumer desc _) = desc ``` -## Descriptions+### Descriptions  A description is like this: @@ -95,7 +95,7 @@ describeArgs :: Description CmdArgs -> Text ``` -## Wrapping+### Wrapping  One can wrap up a consumer to alter either the description or the parser or both, this can be used for wrapping labels, or adding@@ -111,6 +111,16 @@      -- ^ Transform the parser. Can re-run the parser as many times as desired.      -> Consumer t d a      -> Consumer s d b+```++There is also a handy function written in terms of `wrap` which will+validate a consumer.++``` haskell+validate :: d                                              -- ^ Description of what it expects.+         -> (forall m. MonadState s m => a -> m (Maybe b)) -- ^ Attempt to parse the value.+         -> Consumer s d a                                 -- ^ Consumer to add validation to.+         -> Consumer s d b                                 -- ^ A new validating consumer. ```  See below for some examples of this library.
descriptive.cabal view
@@ -1,5 +1,5 @@ name:                descriptive-version:             0.6.0+version:             0.7.0 synopsis:            Self-describing consumers/parsers; forms, cmd-line args, JSON, etc. description:         Self-describing consumers/parsers. See the README.md for more information. It is currently EXPERIMENTAL. stability:           Experimental
src/Descriptive.hs view
@@ -27,6 +27,7 @@  import Control.Applicative import Control.Monad.State.Strict+import Control.Monad.Identity import Data.Bifunctor import Data.Monoid @@ -34,13 +35,13 @@ -- Running  -- | Run a consumer.-consume :: Consumer s d a -- ^ The consumer to run.+consume :: Consumer s d Identity a -- ^ The consumer to run.         -> s -- ^ Initial state.         -> Result (Description d) a consume c s = evalState (runConsumer c) s  -- | Describe a consumer.-describe :: Consumer s d a -- ^ The consumer to run.+describe :: Consumer s d Identity a -- ^ The consumer to run.          -> s -- ^ Initial state. Can be \"empty\" if you don't use it for               -- generating descriptions.          -> Description d -- ^ A description and resultant state.@@ -48,13 +49,13 @@  -- | Run a consumer. runConsumer :: Monad m-            => Consumer s d a -- ^ The consumer to run.+            => Consumer s d m a -- ^ The consumer to run.             -> StateT s m (Result (Description d) a) runConsumer (Consumer _ m) = m  -- | Describe a consumer. runDescription :: Monad m-               => Consumer s d a -- ^ The consumer to run.+               => Consumer s d m a -- ^ The consumer to run.                -> StateT s m (Description d) -- ^ A description and resultant state. runDescription (Consumer desc _) = desc @@ -83,9 +84,9 @@   deriving (Show,Eq)  -- | A consumer.-data Consumer s d a =-  Consumer {consumerDesc :: forall m. Monad m => StateT s m (Description d)-           ,consumerParse :: forall m. Monad m => StateT s m (Result (Description d) a)}+data Consumer s d m a =+  Consumer {consumerDesc :: StateT s m (Description d)+           ,consumerParse :: StateT s m (Result (Description d) a)}  -- | Some result. data Result e a@@ -106,7 +107,7 @@       Failed e -> Failed (f e)       Continued e -> Continued (f e) -instance Functor (Consumer s d) where+instance Monad m => Functor (Consumer s d m) where   fmap f (Consumer d p) =     Consumer d              (do r <- p@@ -118,7 +119,7 @@                    (Succeeded a) ->                      return (Succeeded (f a))) -instance Applicative (Consumer s d) where+instance Monad m => Applicative (Consumer s d m) where   pure a =     consumer (return mempty)              (return (Succeeded a))@@ -150,7 +151,7 @@                        Succeeded a ->                          return (Succeeded (f a))) -instance Alternative (Consumer s d) where+instance Monad m => Alternative (Consumer s d m) where   empty =     consumer (return mempty)              (return (Failed mempty))@@ -186,7 +187,7 @@  -- | An internal sequence maker which describes itself better than -- regular Alternative, and is strict, not lazy.-sequenceHelper :: Integer -> Consumer t d a -> Consumer t d [a]+sequenceHelper :: Monad m => Integer -> Consumer t d m a -> Consumer t d m [a] sequenceHelper minb =   wrap (liftM redescribe)        (\_ p ->@@ -238,7 +239,7 @@           Continued e -> Continued e           Succeeded b -> Succeeded (a <> b) -instance (Monoid a) => Monoid (Consumer s d a) where+instance (Monoid a, Monad m) => Monoid (Consumer s d m a) where   mempty =     consumer (return mempty)              (return mempty)@@ -248,32 +249,33 @@ -- Combinators  -- | Make a self-describing consumer.-consumer :: (forall m. Monad m => StateT s m (Description d))+consumer :: (StateT s m (Description d))          -- ^ Produce description based on the state.-         -> (forall m. Monad m => StateT s m (Result (Description d) a))+         -> (StateT s m (Result (Description d) a))          -- ^ Parse the state and maybe transform it if desired.-         -> Consumer s d a+         -> Consumer s d m a consumer d p =   Consumer d p  -- | Wrap a consumer with another consumer. The type looks more -- intimidating than it actually is. The source code is trivial. It -- simply allows for a way to transform the type of the state.-wrap :: (forall m. Monad m => StateT t m (Description d) -> StateT s m (Description d))+wrap :: (StateT t m (Description d) -> StateT s m (Description d))      -- ^ Transform the description.-     -> (forall m. Monad m => StateT t m (Description d) -> StateT t m (Result (Description d) a) -> StateT s m (Result (Description d) b))+     -> (StateT t m (Description d) -> StateT t m (Result (Description d) a) -> StateT s m (Result (Description d) b))      -- ^ Transform the parser. Can re-run the parser as many times as desired.-     -> Consumer t d a-     -> Consumer s d b+     -> Consumer t d m a+     -> Consumer s d m b wrap redescribe reparse (Consumer d p) =   Consumer (redescribe d)            (reparse d p)  -- | Add validation to a consumer.-validate :: d                                              -- ^ Description of what it expects.-         -> (forall m. MonadState s m => a -> m (Maybe b)) -- ^ Attempt to parse the value.-         -> Consumer s d a                                 -- ^ Consumer to add validation to.-         -> Consumer s d b                                 -- ^ A new validating consumer.+validate :: Monad m +         => d                           -- ^ Description of what it expects.+         -> (a -> StateT s m (Maybe b)) -- ^ Attempt to parse the value.+         -> Consumer s d m a            -- ^ Consumer to add validation to.+         -> Consumer s d m b            -- ^ A new validating consumer. validate d' check =   wrap (liftM wrapper)        (\d p ->
src/Descriptive/Char.hs view
@@ -14,7 +14,7 @@ import qualified Data.Text as T  -- | Consume any character.-anyChar :: Consumer [Char] Text Char+anyChar :: Monad m => Consumer [Char] Text m Char anyChar =   consumer (return d)            (do s <- get@@ -25,7 +25,7 @@   where d = Unit "a character"  -- | A character consumer.-char :: Char -> Consumer [Char] Text Char+char :: Monad m => Char -> Consumer [Char] Text m Char char c =   wrap (liftM (const d))        (\_ p ->@@ -41,7 +41,7 @@   where d = Unit (T.singleton c)  -- | A string consumer.-string :: [Char] -> Consumer [Char] Text [Char]+string :: Monad m => [Char] -> Consumer [Char] Text m [Char] string =   wrap (liftM (Sequence . flattenAnds))        (\_ p -> p) .
src/Descriptive/Form.hs view
@@ -26,7 +26,7 @@   deriving (Show,Eq)  -- | Consume any input value.-input :: Text -> Consumer (Map Text Text) Form Text+input :: Monad m => Text -> Consumer (Map Text Text) Form m Text input name =   consumer (return d)            (do s <- get
src/Descriptive/Formlet.hs view
@@ -31,7 +31,7 @@   deriving (Show,Eq)  -- | Consume any character.-indexed :: Consumer FormletState Formlet Text+indexed :: Monad m => Consumer FormletState Formlet m Text indexed =   consumer (do i <- nextIndex                return (d i))
src/Descriptive/JSON.hs view
@@ -62,9 +62,10 @@   deriving (Eq,Show,Typeable,Data)  -- | Consume an object.-object :: Text -- ^ Description of what the object is.-       -> Consumer Object Doc a -- ^ An object consumer.-       -> Consumer Value Doc a+object :: Monad m+       => Text -- ^ Description of what the object is.+       -> Consumer Object Doc m a -- ^ An object consumer.+       -> Consumer Value Doc m a object desc =   wrap (\d ->           do s <- get@@ -92,9 +93,10 @@   where doc = Object desc  -- | Consume from object at the given key.-key :: Text -- ^ The key to lookup.-    -> Consumer Value Doc a -- ^ A value consumer of the object at the key.-    -> Consumer Object Doc a+key :: Monad m+    => Text -- ^ The key to lookup.+    -> Consumer Value Doc m a -- ^ A value consumer of the object at the key.+    -> Consumer Object Doc m a key k =   wrap (\d ->           do s <- get@@ -117,9 +119,10 @@  -- | Optionally consume from object at the given key, only if it -- exists.-keyMaybe :: Text -- ^ The key to lookup.-         -> Consumer Value Doc a -- ^ A value consumer of the object at the key.-         -> Consumer Object Doc (Maybe a)+keyMaybe :: Monad m+         => Text -- ^ The key to lookup.+         -> Consumer Value Doc m a -- ^ A value consumer of the object at the key.+         -> Consumer Object Doc m (Maybe a) keyMaybe k =   wrap (\d ->           do s <- get@@ -141,9 +144,10 @@   where doc = Key k  -- | Consume an array.-array :: Text -- ^ Description of this array.-      -> Consumer Value Doc a -- ^ Consumer for each element in the array.-      -> Consumer Value Doc (Vector a)+array :: Monad m+      => Text -- ^ Description of this array.+      -> Consumer Value Doc m a -- ^ Consumer for each element in the array.+      -> Consumer Value Doc m (Vector a) array desc =   wrap (\d -> liftM (Wrap doc) d)        (\_ p ->@@ -172,8 +176,9 @@   where doc = Array desc  -- | Consume a string.-string :: Text -- ^ Description of what the string is for.-       -> Consumer Value Doc Text+string :: Monad m+       => Text -- ^ Description of what the string is for.+       -> Consumer Value Doc m Text string doc =   consumer (return d)            (do s <- get@@ -184,8 +189,9 @@   where d = Unit (Text doc)  -- | Consume an integer.-integer :: Text -- ^ Description of what the integer is for.-        -> Consumer Value Doc Integer+integer :: Monad m+        => Text -- ^ Description of what the integer is for.+        -> Consumer Value Doc m Integer integer doc =   consumer (return d)            (do s <- get@@ -197,8 +203,9 @@   where d = Unit (Integer doc)  -- | Consume an double.-double :: Text -- ^ Description of what the double is for.-       -> Consumer Value Doc Double+double :: Monad m+       => Text -- ^ Description of what the double is for.+       -> Consumer Value Doc m Double double doc =   consumer (return d)            (do s <- get@@ -209,8 +216,9 @@   where d = Unit (Double doc)  -- | Parse a boolean.-bool :: Text -- ^ Description of what the bool is for.-     -> Consumer Value Doc Bool+bool :: Monad m+     => Text -- ^ Description of what the bool is for.+     -> Consumer Value Doc m Bool bool doc =   consumer (return d)            (do s <- get@@ -221,8 +229,9 @@   where d = Unit (Boolean doc)  -- | Expect null.-null :: Text -- ^ What the null is for.-       -> Consumer Value Doc ()+null :: Monad m+     => Text -- ^ What the null is for.+     -> Consumer Value Doc m () null doc =   consumer (return d)            (do s <- get@@ -233,9 +242,10 @@   where d = Unit (Null doc)  -- | Wrap a consumer with a label e.g. a type tag.-label :: Text             -- ^ Some label.-      -> Consumer s Doc a -- ^ A value consumer.-      -> Consumer s Doc a+label :: Monad m+      => Text               -- ^ Some label.+      -> Consumer s Doc m a -- ^ A value consumer.+      -> Consumer s Doc m a label desc =   wrap (liftM (Wrap doc))        (\_ p ->@@ -247,9 +257,10 @@   where doc = Label desc  -- | Wrap a consumer with some handy information.-info :: Text             -- ^ Some information.-     -> Consumer s Doc a -- ^ A value consumer.-     -> Consumer s Doc a+info :: Monad m+     => Text               -- ^ Some information.+     -> Consumer s Doc m a -- ^ A value consumer.+     -> Consumer s Doc m a info desc =   wrap (liftM (Wrap doc))        (\_ p ->
src/Descriptive/Options.hs view
@@ -46,9 +46,10 @@  -- | If the consumer succeeds, stops the whole parser and returns -- 'Stopped' immediately.-stop :: Consumer [Text] (Option a) a+stop :: Monad m+     => Consumer [Text] (Option a) m a      -- ^ A parser which, when it succeeds, causes the whole parser to stop.-     -> Consumer [Text] (Option a) ()+     -> Consumer [Text] (Option a) m () stop =   wrap (liftM (Wrap Stops))        (\d p ->@@ -66,8 +67,9 @@  -- | Consume one argument from the argument list and pops it from the -- start of the list.-anyString :: Text -- Help for the string.-          -> Consumer [Text] (Option a) Text+anyString :: Monad m+          => Text -- Help for the string.+          -> Consumer [Text] (Option a) m Text anyString help =   consumer (return d)            (do s <- get@@ -79,10 +81,11 @@  -- | Consume one argument from the argument list which must match the -- given string, and also pops it off the argument list.-constant :: Text -- ^ String.+constant :: Monad m+         => Text -- ^ String.          -> Text -- ^ Description.          -> v-         -> Consumer [Text] (Option a) v+         -> Consumer [Text] (Option a) m v constant x' desc v =   consumer (return d)            (do s <- get@@ -95,10 +98,11 @@  -- | Find a value flag which must succeed. Removes it from the -- argument list if it succeeds.-flag :: Text -- ^ Name.+flag :: Monad m+     => Text -- ^ Name.      -> Text -- ^ Description.      -> v    -- ^ Value returned when present.-     -> Consumer [Text] (Option a) v+     -> Consumer [Text] (Option a) m v flag name help v =   consumer (return d)            (do s <- get@@ -110,18 +114,20 @@  -- | Find a boolean flag. Always succeeds. Omission counts as -- 'False'. Removes it from the argument list if it returns True.-switch :: Text -- ^ Name.+switch :: Monad m+       => Text -- ^ Name.        -> Text -- ^ Description.-       -> Consumer [Text] (Option a) Bool+       -> Consumer [Text] (Option a) m Bool switch name help =   flag name help True <|>   pure False  -- | Find an argument prefixed by -X. Removes it from the argument -- list when it succeeds.-prefix :: Text -- ^ Prefix string.+prefix :: Monad m+       => Text -- ^ Prefix string.        -> Text -- ^ Description.-       -> Consumer [Text] (Option a) Text+       -> Consumer [Text] (Option a) m Text prefix pref help =   consumer (return d)            (do s <- get@@ -133,9 +139,10 @@  -- | Find a named argument e.g. @--name value@. Removes it from the -- argument list when it succeeds.-arg :: Text -- ^ Name.+arg :: Monad m+    => Text -- ^ Name.     -> Text -- ^ Description.-    -> Consumer [Text] (Option a) Text+    -> Consumer [Text] (Option a) m Text arg name help =   consumer (return d)            (do s <- get
src/test/Main.hs view
@@ -164,7 +164,7 @@              ,submissionSubreddit :: !Integer}   deriving (Show,Eq) -submission :: Consumer Value JSON.Doc Submission+submission :: Monad m => Consumer Value JSON.Doc m Submission submission =   JSON.object "Submission"               (Submission