Closed vil1 closed 5 years ago
I don't quite follow the annotation logic you employ during the coalgebra. you start out with a false, a record causes any further nodes to carry along a true, a
:*:
passes false to left and carries along on the right and any other just carries the flag along.but shouldn't a record pass a true to all immediate children and in any other case pass a false?
This needs clarification indeed.
What I want is to label with true
all the "chain" of :*:
that are under a Record
, but not their children.
So I schematically (no pun intended) end up with something like:
false -> Record(
true -> :*:(
false -> x // <- is guarantied to be a ProductTerm,
true -> :*:(
false -> y,
true -> z // also guarantied to be a ProductTerm
)
)
)
The "last child" (here z
) ends up labelled with true
but it doesn't matter (it is guarantied to be a ProductTerm
and I don't use the label for rendering those).
Does that make more sense?
This PR adds interpreters for (en|de)coders to/from the Play! JSON AST in a
playJson
module, and is therefore part of #32.More specifically, it introduces interpreters for
play.api.libs.json.Reads
andplay.api.libs.json.Writes
.JSON having no standard support for mere products (aka tuples), I had to make a decision about how we represent such mere products. At the same time, I had to devise a way to handle differently products that are part of a
Record
(which must be represented as flatJsObject
s) and "mere products" (represented as I arbitrarily decided).Solving that problem made me introduce
HCoalgebra
,hyloNT
andHEnvT
.HCoalgebra
is the dual ofHAlgebra
, ie. a natural transformationF ~> S[F, ?]
hyloNT
is a recursion scheme that uses both anHCoalgebra
andHAlgebra
. It builds up a tree (here, some schema flavour) using theHCoalgebra
and then collapses if (into a target functorF
) using theHAlgebra
.HEnvT
is a mean for labelling nodes of a tree (here a schema) with values of some given type, while retaining the structure of that tree (schema).These three constructs are used to derive
Reads
andWrites
from a schema.First I use an
HCoalgebra
to "push-down" information (usingHEnvT
) so that every:*:
node "knows" if it's part of aRecord
or not, and then I use this information in theHAlgebra
to decide how to render this particular:*:
node.The
:*:
nodes that are under aRecord
node are rendered as a singleJsObject
: we know that these nodes contain onlyProductTerm
s which are rendered asJsObject
with a single field, theseJsObject
s are then merged to form the record's representation.Other
:*:
node are considered as tuples, which are (debatably) rendered as{ "_1": "foo", "_2": { "_1": "bar", "_2": ...}}
.Tests ensure that the
Reads
andWrites
derived from a given schema are symmetrical, ie.reads(writes(data)) == data
.