Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reflect the internal (real) type of Value with a type parameter (like in GADTs for syntactic terms) #260

Closed
imz opened this issue Jun 4, 2015 · 3 comments

Comments

@imz
Copy link

imz commented Jun 4, 2015

Sometimes a JSON-based format dictates that we must have, say, a JSON "object" at some place (and other types would break the format).

It would be nice to make these things expressable in the Haskell types (with a type parameter of Value).

Also often people want to re-use the result of toJSON, but they really expect a specific type when they deconstruct it. (Like in the motivation for #245, which I find quite ugly.) The compiler could check these assumptions and give guarantees.

(I have a few examples of both kinds in my code: adhering to a stricter JSON format, and decontructing the result of toJSON.)

Actually, sometimes there are different variants how to encode a data type; the Aeson options can control this. But one could perhaps even have several ToJSON instances for such data, if the class is parameterized with the type of the resulting JSON value.

I'm not sure whether this can be done smoothly (automatically, with as little manual annotations as possible) with the Generics machinery.

@imz
Copy link
Author

imz commented Jun 4, 2015

One problem with implementing such GADT annotations for Value which I see now is the types for the elements of JSON objects or JSON arrays: fi we track them, then we should have a series of types for non-uniform lists of Value x (where all x can be different). (I mean "heterogeneous" lists.)

But we might not care about deep type annotations, only use practically the one from the top only. And represent objects and arrays with elements of type forall x. Value x -- this we'd erase the information about the deeper values for those who will access them later (i.e., have the same situation as we have with current Aeson).

Processing Values with unknown type annotations

Well... how do we pattern-match on GADTs when the constructors belong to different types?..

I believe that having a value of type like forall x. Value x we can't pattern match on it with--say--Object o.

So, now I think about a design where the annotated types are an internal thing, and the JSON types can be made untyped with a method of a dedicated class which would give the old simple Value for any new annotated Value' x.

(Cf. Haskell Antipattern: Existential Typeclass.)

What do you think about the reasonability of going forward and implementing all this? (I could try to.)

This was referenced Jun 4, 2015
@imz
Copy link
Author

imz commented Jun 4, 2015

Perhaps, we could live without GADTs, but with a bunch of classes like ToJsonString, ToJsonObject with generic default implementation coming from the current Aeson. Not sure whether the Generics allow such partial default implementations. (Not for all possible Generic types.) Probably, not...

@bos
Copy link
Collaborator

bos commented Jun 9, 2015

This is not a design space that aeson can explore, due to its backwards incompatibility. I recommend you try the idea out in a smaller, simpler package of your own and see how well it works in practice.

@bos bos closed this as completed Jun 9, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants