úÎWâUŽ     © 2017 2018 Mark Karpov BSD 3 clause$Mark Karpov <markkarpov92@gmail.com> experimentalportableNone-3;=>?FSTV]bTéThe type function computes a € which is satisfied when its first argument is contained in its second argument. Otherwise a friendly type error is displayed. names" represents a non-empty vector of q components that serve as a path to some field in a JSON structure. Every component is guaranteed to be in the namesÙ, which is a set of strings on type level. The purpose if this type is to avoid typos and to force users to update field names everywhere when they decide to change them. The only way to obtain a value of the type  is by using OverloadedLabels.. Note that you can combine field names using (). @showFieldName (#login_form <> #username) = "login_form.username"5The type represents the parser that you can run on a   with the help of J. The only way for the user of the library to create a parser is via the  e function and its friends, see below. Users can combine existing parsers using applicative notation.( is parametrized by four type variables:namesU collection of field names we can use in a form to be parsed with this parser.e type of validation errors.m underlying monad, c is not a monad itself, so it's not a monad transformer, but validation can make use of the m monad.a result of parsing.5 is not a monad because it's not possible to write a !k instance with the properties that we want (validation errors should not lead to short-cutting behavior).Result of parsing. names, is the collection of allowed field names, e' is the type of validation errors, and a is the type of parsing result.ÄParsing of JSON failed, this is fatal, we shut down and report the parsing error. The first component specifies path to a problematic field and the second component is the text of error message.™Validation of a field failed. This is also fatal but we still try to validate other branches (fields) to collect as many validation errors as possible.&Success, we've got a result to return.Project field path from a .2Project textual representation of path to a field. 1Construct a parser for a field. Combine multiple  $s using applicative syntax like so: ÿötype LoginFields = '["username", "password", "remember_me"] data LoginForm = LoginForm { loginUsername :: Text , loginPassword :: Text , loginRememberMe :: Bool } loginForm :: Monad m => FormParser LoginFields Text m LoginForm loginForm = LoginForm <$> field #username notEmpty <*> field #password notEmpty <*> field' #remember_me notEmpty :: Monad m => Text -> ExceptT Text m Text notEmpty txt = if T.null txt then throwError "This field cannot be empty" else return txt4Referring to the types in the function's signature, s is extracted from JSON  ! for you automatically using its "B instance. The field value is taken in assumption that top level  ‰ is a dictionary, and field name is a key in that dictionary. So for example a valid JSON input for the form shown above could be this: C{ "username": "Bob", "password": "123", "remember_me": true }Once value of type s` is extracted, validation phase beings. The supplied checker (you can easily compose them with (#)1, as they are Kleisli arrows) is applied to the s4 value and validation either succeeds producing an a- value, or we collect an error as a value of e type.To run a form composed from  s, see . Dfield fieldName check = withCheck fieldName check (field' fieldName)  The same as  !, but does not require a checker. ,field' fieldName = subParser fieldName value /Interpret the current field as a value of type a. EUse a given parser to parse a field. Suppose that you have a parser  loginForm' that parses a structure like this one: C{ "username": "Bob", "password": "123", "remember_me": true }Then subParser #login loginForm will parse this: ^{ "login": { "username": "Bob", "password": "123", "remember_me": true } } 5Transform a form by applying a checker on its result. ÿpasswordsMatch (a, b) = do if a == b then return a else throwError "Passwords don't match!" passwordForm = withCheck #password_confirmation passwordsMatch ((,) <$> field #password notEmpty <*> field #password_confirmation notEmpty)ÿNote that you must specify the field name on which to add a validation error message in case the check fails. The field name should be relative and point to a field in the argument parser, not full path from top-level of the form. For example this form: 2biggerForm = subParser #password_form passwordForm,will report validation error for the field %"password_form.password_confirmation" if the check fails (note that "password_form"+ is correctly prepended to the field path).Run a parser on given input.$(Fixup a error message returned by Aeson.%Like  but for &. Name of the fieldPChecker that performs validation and possibly transformation of the field value Name of the field Field name to descend to SubparserWrapped parser #Field to assign validation error toThe check to performOriginal parserParser with the check attachedThe form parser to runInput for the parserThe result of parsing  '()*      !"#$%&'()*+,'-.*/0'1234'(567"forma-1.0.0-FQRDwiwhVuIJJYFfzz9IwM Web.Forma Data.Maybe fromMaybeInSet FieldName FormParser FormResult ParsingFailedValidationFailed Succeeded unFieldName showFieldNamefieldfield'value subParser withCheckrunForm$fToJSONFieldName$fSemigroupFieldName$fApplicativeFormResult$fToJSONFormResult$fAlternativeFormParser$fApplicativeFormParser$fFunctorFormParser$fIsLabelnameFieldName $fEqFieldName$fOrdFieldName$fShowFieldName$fEqFormResult$fShowFormResult$fFunctorFormResultghc-prim GHC.Types Constraint#text-1.2.2.2-EakMpasry3jA6OIwSZhq9MData.Text.InternalTextbaseData.Semigroup<>$aeson-1.2.4.0-HJ6Tijnh81vLD043xgUX94Data.Aeson.Types.InternalValueGHC.BaseMonadData.Aeson.Types.FromJSONFromJSON Control.Monad>=>fixupAesonError fromOptionOption unFormParser