Recognizing lists

In relation to the input validation post, on a similar track I'm developing a library called descriptive (WIP and experimental, don't publish it anywhere please) which attempts to generalize the notion of parsers which describe what they expect as input. The whole package is basically this module, the other modules are example uses. My main motivation is for this project, but it seemed that formlets and commandline parsers are the same thing. In playing with that I discovered that it also works great for JSON parsing. The describe combinator I can use to generate documentation, and the consume operator I can use to parse and generate "errors" (which are really just re-stating the description but narrowed):

λ> describe submission (toJSON ())
Wrap (Object "Submission")
     (And (And (And (Wrap (Key "token")
                          (Unit (Integer "Submission token; see the API docs")))
                    (Wrap (Key "title")
                          (Unit (Text "Submission title"))))
               (Wrap (Key "comment")
                     (Unit (Text "Submission comment"))))
          (Wrap (Key "subreddit")
                (Unit (Integer "The ID of the subreddit"))))

One can take this and produce documentation out of it. Collapse the And branches into a list if you like. If there's an Or, then your docs can actually display a branch of choices, etc.

λ> consume submission sample
Succeeded (Submission {submissionToken = 123
                      ,submissionTitle = "Some title"
                      ,submissionComment = "This is good"
                      ,submissionSubreddit = 234214})
λ> consume submission badsample
Failed (Wrap (Object "Submission")
             (Wrap (Key "comment")
                   (Unit (Text "Submission comment"))))

This is basically "I expected the object Submission with a key 'comment' whose type should be a string field and by the way here's the documentation for that field: Submission comment". Pretty print this in a way that you like. As a JSON structure or plain text.

The validate combinator can be used to add validation and the Label a constructor in the JSON description AST can be used to wrap nodes with any kind of semantic information useful for your app.

/r/haskell Thread Link - ro-che.info