-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Invertible parsing combinators framework
--   
--   Grammar combinator framework to build invertible parsing libraries for
--   concrete syntax.
@package invertible-grammar
@version 0.1.1

module Data.InvertibleGrammar.Base

-- | Representation of an invertible grammar -- a grammar that can be run
--   either "forwards" and "backwards".
--   
--   For a grammar <tt>Grammar p a b</tt>, running it forwards will take a
--   value of type <tt>a</tt> and possibly produce a value of type
--   <tt>b</tt>. Running it backwards will take a value of type <tt>b</tt>
--   and possibly produce an <tt>a</tt>. If a value cannot be produced, an
--   error message is generated.
--   
--   As a common example, running a <a>Grammar</a> forwards corresponds to
--   parsing and running backwards corresponds to prettyprinting.
--   
--   That is, the grammar defines a partial isomorphism between two values.
data Grammar p a b

-- | Total isomorphism grammar.
[Iso] :: (a -> b) -> (b -> a) -> Grammar p a b

-- | Partial isomorphism. Use <a>Flip</a> to change the direction of
--   partiality.
[PartialIso] :: (a -> b) -> (b -> Either Mismatch a) -> Grammar p a b

-- | Flip forward and backward passes of an underlying grammar.
[Flip] :: Grammar p a b -> Grammar p b a

-- | Grammar composition.
[:.:] :: Grammar p b c -> Grammar p a b -> Grammar p a c

-- | Grammar alternation. Left operand is tried first.
[:<>:] :: Grammar p a b -> Grammar p a b -> Grammar p a b

-- | Application of a grammar on <a>Traversable</a> functor.
[Traverse] :: (Traversable f) => Grammar p a b -> Grammar p (f a) (f b)

-- | Applicaiton of a grammar on stack head (first component of <a>:-</a>).
[OnHead] :: Grammar p a b -> Grammar p (a :- t) (b :- t)

-- | Applicaiton of a grammar on stack tail (second component of
--   <a>:-</a>).
[OnTail] :: Grammar p a b -> Grammar p (h :- a) (h :- b)

-- | Application of a grammar inside a context of annotation, used for
--   error messages.
[Annotate] :: Text -> Grammar p a b -> Grammar p a b

-- | Application of a grammar inside a context of a nested structure, used
--   for error messages. E.g. JSON arrays.
[Dive] :: Grammar p a b -> Grammar p a b

-- | Propagate logical position inside a nested structure. E.g. after each
--   successfully matched element of a JSON array.
[Step] :: Grammar p a a

-- | Update the position of grammar monad from value on grammar's input or
--   output on forward or backward pass, respectively. Used for error
--   messages.
[Locate] :: Grammar p p p

-- | "Cons" pair of a heterogenous list or a stack with potentially
--   polymophic tail. E.g. <tt>"first" :- 2 :- (3,4) :- t</tt>
--   
--   Isomorphic to a tuple with two elments, but is much more convenient
--   for nested pairs.
data h (:-) t
(:-) :: h -> t -> (:-) h t

-- | Run <a>Grammar</a> forwards.
--   
--   For <tt>Grammar p a b</tt>, given a value of type <tt>a</tt> tries to
--   produce a value of type <tt>b</tt>, otherwise reports an error with
--   position of type <tt>p</tt>.
forward :: Grammar p a b -> a -> ContextError (Propagation p) (GrammarError p) b

-- | Run <a>Grammar</a> backwards.
--   
--   For <tt>Grammar p a b</tt>, given a value of type <tt>b</tt> tries to
--   produce a value of type <tt>a</tt>, otherwise reports an error with
--   position of type <tt>p</tt>.
backward :: Grammar p a b -> b -> ContextError (Propagation p) (GrammarError p) a
data GrammarError p
GrammarError :: (Propagation p) -> Mismatch -> GrammarError p

-- | Data type to encode mismatches during parsing or generation, kept
--   abstract. Use <a>expected</a> and <a>unexpected</a> constructors to
--   build a mismatch report.
data Mismatch

-- | Construct a mismatch report with specified expectation. Can be
--   appended to other expectations and <a>unexpected</a> reports to
--   clarify a mismatch.
expected :: Text -> Mismatch

-- | Construct a mismatch report with information what occurred during the
--   processing but was not expected.
unexpected :: Text -> Mismatch
instance Data.Traversable.Traversable ((Data.InvertibleGrammar.Base.:-) h)
instance Data.Foldable.Foldable ((Data.InvertibleGrammar.Base.:-) h)
instance GHC.Base.Functor ((Data.InvertibleGrammar.Base.:-) h)
instance (GHC.Show.Show h, GHC.Show.Show t) => GHC.Show.Show (h Data.InvertibleGrammar.Base.:- t)
instance (GHC.Classes.Eq h, GHC.Classes.Eq t) => GHC.Classes.Eq (h Data.InvertibleGrammar.Base.:- t)
instance Control.Category.Category (Data.InvertibleGrammar.Base.Grammar p)
instance GHC.Base.Semigroup (Data.InvertibleGrammar.Base.Grammar p a b)
instance Data.Bifunctor.Bifunctor (Data.InvertibleGrammar.Base.:-)
instance Data.Bifoldable.Bifoldable (Data.InvertibleGrammar.Base.:-)
instance Data.Bitraversable.Bitraversable (Data.InvertibleGrammar.Base.:-)

module Data.InvertibleGrammar.Generic

-- | Provide a data constructor/stack isomorphism to a grammar working on
--   stacks. Works for types with one data constructor. For sum types use
--   <a>match</a> and <a>Coproduct</a>.
with :: forall a b s t c d f p. (Generic a, MkPrismList (Rep a), MkStackPrism f, Rep a ~ M1 D d (M1 C c f), StackPrismLhs f t ~ b, Constructor c) => (Grammar p b (a :- t) -> Grammar p s (a :- t)) -> Grammar p s (a :- t)

-- | Combine all grammars provided in <a>Coproduct</a> list into a single
--   grammar.
match :: (Generic a, MkPrismList (Rep a), Match (Rep a) bs t, bs ~ Coll (Rep a) t) => Coproduct p s bs a t -> Grammar p s (a :- t)

-- | Heterogenous list of grammars, each one matches a data constructor of
--   type <tt>a</tt>. <a>With</a> is used to provide a data
--   constructor/stack isomorphism to a grammar working on stacks.
--   <a>End</a> ends the list of matches.
data Coproduct p s bs a t
[With] :: (Grammar p b (a :- t) -> Grammar p s (a :- t)) -> Coproduct p s bs a t -> Coproduct p s (b : bs) a t
[End] :: Coproduct p s '[] a t
instance Data.InvertibleGrammar.Generic.MkStackPrism f => Data.InvertibleGrammar.Generic.MkPrismList (GHC.Generics.M1 GHC.Generics.C c f)
instance Data.InvertibleGrammar.Generic.MkStackPrism GHC.Generics.U1
instance Data.InvertibleGrammar.Generic.MkStackPrism (GHC.Generics.K1 i a)
instance Data.InvertibleGrammar.Generic.MkStackPrism f => Data.InvertibleGrammar.Generic.MkStackPrism (GHC.Generics.M1 i c f)
instance (Data.InvertibleGrammar.Generic.MkStackPrism f, Data.InvertibleGrammar.Generic.MkStackPrism g) => Data.InvertibleGrammar.Generic.MkStackPrism (f GHC.Generics.:*: g)
instance (Data.InvertibleGrammar.Generic.StackPrismLhs f t ~ b, GHC.Generics.Constructor c) => Data.InvertibleGrammar.Generic.Match (GHC.Generics.M1 GHC.Generics.C c f) (b : bs) t
instance Data.InvertibleGrammar.Generic.MkPrismList f => Data.InvertibleGrammar.Generic.MkPrismList (GHC.Generics.M1 GHC.Generics.D c f)
instance (Data.InvertibleGrammar.Generic.MkPrismList f, Data.InvertibleGrammar.Generic.MkPrismList g) => Data.InvertibleGrammar.Generic.MkPrismList (f GHC.Generics.:+: g)
instance (Data.InvertibleGrammar.Generic.Match f bs t, Data.InvertibleGrammar.Generic.Trav f bs ~ '[]) => Data.InvertibleGrammar.Generic.Match (GHC.Generics.M1 GHC.Generics.D c f) bs t
instance (Data.InvertibleGrammar.Generic.Match f bs t, Data.InvertibleGrammar.Generic.Match g (Data.InvertibleGrammar.Generic.Trav f bs) t) => Data.InvertibleGrammar.Generic.Match (f GHC.Generics.:+: g) bs t

module Data.InvertibleGrammar.Combinators

-- | Isomorphism on the stack head.
iso :: (a -> b) -> (b -> a) -> Grammar p (a :- t) (b :- t)

-- | Flipped isomorphism on the stack head.
osi :: (b -> a) -> (a -> b) -> Grammar p (a :- t) (b :- t)

-- | Partial isomorphism (for backward run) on the stack head.
partialIso :: (a -> b) -> (b -> Either Mismatch a) -> Grammar p (a :- t) (b :- t)

-- | Partial isomorphism (for forward run) on the stack head.
partialOsi :: (a -> Either Mismatch b) -> (b -> a) -> Grammar p (a :- t) (b :- t)

-- | Push an element to the stack on forward run, check if the element
--   satisfies predicate, otherwise report a mismatch.
push :: a -> (a -> Bool) -> (a -> Mismatch) -> Grammar p t (a :- t)

-- | 2-tuple grammar. Construct on forward run, deconstruct on backward
--   run.
pair :: Grammar p (b :- a :- t) ((a, b) :- t)

-- | Swap two topmost stack elements.
swap :: Grammar p (a :- b :- t) (b :- a :- t)

-- | List cons-cell grammar. Construct on forward run, deconstruct on
--   backward run.
cons :: Grammar p ([a] :- a :- t) ([a] :- t)

-- | Empty list grammar. Construct empty list on forward run, check if list
--   is empty on backward run.
nil :: Grammar p t ([a] :- t)

-- | Assoc-list element grammar. Inserts an element (with static key) on
--   forward run, look up an element on backward run.
insert :: (Eq k) => k -> Mismatch -> Grammar p (v :- [(k, v)] :- t) ([(k, v)] :- t)

-- | Optional assoc-list element grammar. Like <a>insert</a>, but does not
--   report a mismatch on backward run. Instead takes and produces a
--   Maybe-value.
insertMay :: (Eq k) => k -> Grammar p (Maybe v :- [(k, v)] :- t) ([(k, v)] :- t)

-- | Default value grammar. Replaces <a>Nothing</a> with a default value on
--   forward run, an replaces a default value with <a>Nothing</a> on
--   backward run.
toDefault :: (Eq a) => a -> Grammar p (Maybe a :- t) (a :- t)

-- | Join alternative grammars in parallel.
coproduct :: [Grammar p a b] -> Grammar p a b

-- | Focus a given grammar to the stack head.
onHead :: Grammar p a b -> Grammar p (a :- t) (b :- t)

-- | Focus a given grammar to the stack tail.
onTail :: Grammar p ta tb -> Grammar p (h :- ta) (h :- tb)

-- | Traverse a structure with a given grammar.
traversed :: (Traversable f) => Grammar p a b -> Grammar p (f a) (f b)

-- | Run a grammar with inputs and outputs flipped.
flipped :: Grammar p a b -> Grammar p b a

-- | Run a grammar operating on the stack head in a context where there is
--   no stack.
sealed :: Grammar p (a :- Void) (b :- Void) -> Grammar p a b

-- | Run a grammar with the stack heads coerced to other (<a>Coercible</a>)
--   types.
coerced :: (Coercible a c, Coercible b d) => Grammar p (a :- t) (b :- t') -> Grammar p (c :- t) (d :- t')

-- | Run a grammar with an annotation.
annotated :: Text -> Grammar p a b -> Grammar p a b

module Data.InvertibleGrammar

-- | Representation of an invertible grammar -- a grammar that can be run
--   either "forwards" and "backwards".
--   
--   For a grammar <tt>Grammar p a b</tt>, running it forwards will take a
--   value of type <tt>a</tt> and possibly produce a value of type
--   <tt>b</tt>. Running it backwards will take a value of type <tt>b</tt>
--   and possibly produce an <tt>a</tt>. If a value cannot be produced, an
--   error message is generated.
--   
--   As a common example, running a <a>Grammar</a> forwards corresponds to
--   parsing and running backwards corresponds to prettyprinting.
--   
--   That is, the grammar defines a partial isomorphism between two values.
data Grammar p a b

-- | "Cons" pair of a heterogenous list or a stack with potentially
--   polymophic tail. E.g. <tt>"first" :- 2 :- (3,4) :- t</tt>
--   
--   Isomorphic to a tuple with two elments, but is much more convenient
--   for nested pairs.
data h (:-) t

-- | Run <a>Grammar</a> forwards.
--   
--   For <tt>Grammar p a b</tt>, given a value of type <tt>a</tt> tries to
--   produce a value of type <tt>b</tt>, otherwise reports an error with
--   position of type <tt>p</tt>.
forward :: Grammar p a b -> a -> ContextError (Propagation p) (GrammarError p) b

-- | Run <a>Grammar</a> backwards.
--   
--   For <tt>Grammar p a b</tt>, given a value of type <tt>b</tt> tries to
--   produce a value of type <tt>a</tt>, otherwise reports an error with
--   position of type <tt>p</tt>.
backward :: Grammar p a b -> b -> ContextError (Propagation p) (GrammarError p) a

-- | Run a <tt>forward</tt> or <tt>backward</tt> pass of a
--   <tt>Grammar</tt>.
runGrammar :: p -> ContextError (Propagation p) (GrammarError p) a -> Either (ErrorMessage p) a

-- | Run a <tt>forward</tt> or <tt>backward</tt> pass of a
--   <tt>Grammar</tt>, report errors as pretty printed <a>Doc</a> message.
runGrammarDoc :: (Pretty p) => p -> ContextError (Propagation p) (GrammarError p) a -> Either (Doc ann) a

-- | Run a <tt>forward</tt> or <tt>backward</tt> pass of a
--   <tt>Grammar</tt>, report errors as <a>String</a> message.
runGrammarString :: (Show p) => p -> ContextError (Propagation p) (GrammarError p) a -> Either String a

-- | <tt>Grammar</tt> run error messages type.
data ErrorMessage p
ErrorMessage :: p -> [Text] -> Set Text -> Maybe Text -> ErrorMessage p
[emPosition] :: ErrorMessage p -> p
[emAnnotations] :: ErrorMessage p -> [Text]
[emExpected] :: ErrorMessage p -> Set Text
[emGot] :: ErrorMessage p -> Maybe Text
type ContextError c e a = ContextErrorT c e Identity a
data Propagation p
data GrammarError p

-- | Data type to encode mismatches during parsing or generation, kept
--   abstract. Use <a>expected</a> and <a>unexpected</a> constructors to
--   build a mismatch report.
data Mismatch

-- | Construct a mismatch report with specified expectation. Can be
--   appended to other expectations and <a>unexpected</a> reports to
--   clarify a mismatch.
expected :: Text -> Mismatch

-- | Construct a mismatch report with information what occurred during the
--   processing but was not expected.
unexpected :: Text -> Mismatch

module Data.InvertibleGrammar.TH

-- | Build a prism and the corresponding grammar that will match on the
--   given constructor and convert it to reverse sequence of :- stacks.
--   
--   E.g. consider a data type:
--   
--   <pre>
--   data FooBar a b c = Foo a b c | Bar
--   </pre>
--   
--   For constructor Foo
--   
--   <pre>
--   fooGrammar = $(grammarFor 'Foo)
--   </pre>
--   
--   will expand into
--   
--   <pre>
--   fooGrammar = PartialIso
--     (\(c :- b :- a :- t) -&gt; Foo a b c :- t)
--     (\case { Foo a b c :- t -&gt; Just $ c :- b :- a :- t; _ -&gt; Nothing })
--   </pre>
--   
--   Note the order of elements on the stack:
--   
--   <pre>
--   ghci&gt; :t fooGrammar
--   fooGrammar :: Grammar p (c :- (b :- (a :- t))) (FooBar a b c :- t)
--   </pre>
grammarFor :: Name -> ExpQ

-- | Build prisms and corresponding grammars for all data constructors of
--   given type. Expects grammars to zip built ones with.
--   
--   <pre>
--   $(match ''Maybe)
--   </pre>
--   
--   Will expand into a lambda:
--   
--   <pre>
--   (\nothingG justG -&gt; ($(grammarFor 'Nothing) . nothingG) &lt;&gt;
--                       ($(grammarFor 'Just)    . justG))
--   </pre>
match :: Name -> ExpQ
constructors :: Dec -> Maybe (Bool, [Con])
findConstructor :: Name -> [Con] -> Maybe Con
constructorNames :: Con -> Set Name
fieldTypes :: Con -> [Type]
