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

Custom encoding of variants #27

Open
kit-ty-kate opened this issue Apr 13, 2015 · 8 comments · May be fixed by #155
Open

Custom encoding of variants #27

kit-ty-kate opened this issue Apr 13, 2015 · 8 comments · May be fixed by #155

Comments

@kit-ty-kate
Copy link
Collaborator

Hi,

I've the following json format to parse:
I can have either:

{"type":"address", "content":string}

or:

{"type":"coord", "content":{"latitude":float, "longitude":float}}

And what I would like to do is something like that:

type geo_coord =
  { latitude : float
  ; longitude : float
  } [@@deriving yojson]

type coord =
  | Adresse [@name "address"] of string
  | GeoCoordinates [@name "coord"] of geo_coord
  [@@deriving yojson]
  [@@deriving_field_name "type"]

Is it already possible to do something like that or otherwise, is it possible to add such a feature ?

@whitequark
Copy link
Collaborator

No, this is not possible.

The problem with adding this as a feature is that it is not flexible; there is no single format JSON APIs use for serializing sum types.

@kit-ty-kate
Copy link
Collaborator Author

Ok, no problems. I just used Yojson.Safe.json

@whitequark
Copy link
Collaborator

I'm actually open to ideas in regards to this, I just don't know how/if it can be implemented without bloating the interface terribly.

@kit-ty-kate
Copy link
Collaborator Author

Mmmh at least allowing [@name "name"] on record fields would be very helpful.
The field has name type, but it's an ocaml keyword so I can't create the field.

@kit-ty-kate kit-ty-kate reopened this Apr 13, 2015
@kit-ty-kate
Copy link
Collaborator Author

By the way, generally speaking, with ppx is it possible to enforce that attributes (such as ``[@name "name"]`) have to be used by a ppx module ?

@whitequark
Copy link
Collaborator

https://github.com/whitequark/ppx_deriving_yojson#options

And to the second question, no. There's been discussion on schemas on mantis but those are vaporware.

@kit-ty-kate
Copy link
Collaborator Author

Ohh thanks a lot !

@foretspaisibles
Copy link

I have to deal with similar json schemes, I usually handle this the following way:

  1. I define functions adresse_of_yojson : json -> [>Ok of string | Error of string]andgeo_coord_of_yojson : json -> [> Ok of geo_coord | Error of string] and have to bind them in a monadic way, which – without cutting through monadic operators – boils down to
match adresse_of_yojson json  with
| `Ok(a) -> `Ok(Adresse(a))
| `Error(_) ->
  begin match geo_coord_of_yojson json with
  | `Ok(c) -> `Ok(GeoCoordinates(c))
  | `Error(_) as error -> error
end

It is not very easy to figure out a solution that will work with all popular APIs because they all have their pecularities. Maybe an acceptable solution would be the ability to specify for a specific field a family of deserialisers that would have to be tried sequentially deserailse the json structure.

I am not sure how this feature should be combined with variants – should they return Adresse(a) or just a ? In the former case the extension interface would be clean and lean, in the latter case, it would save red typing for the programmer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants