ocaml-ppx / ppx_deriving_yojson

A Yojson codec generator for OCaml.
MIT License
155 stars 46 forks source link

Does ppx_deriving_yojson support GADTs, or am I using it completely wrong? #87

Open ELLIOTTCABLE opened 5 years ago

ELLIOTTCABLE commented 5 years ago

Hi! I'm still pretty new to strictly typed languages in general, much less OCaml — maybe a year or so — so forgive me if this is suuuuuper obvious! Don't want to waste anybody's time!

So, I've got a pretty central type from my lexer that looks like this:

type 'a located = 'a * Lexing.position * Lexing.position

I'm consuming it in a file that I'm trying to use Yojson in; but I need a custom located_to_yojson function that basically discards the location-information:

open Lexer

let located_to_yojson (next : 'a -> Yojson.Safe.json) (x : 'a located) =
   let (x', _, _) = x in
   next x'

type _ node =
 | Comment : string located -> string located node
 | Node : 'a located -> 'a located node
[@@deriving to_yojson]

(* --- 8< ----- *)

Unfortunately, this isn't working as expected — I'm getting this … rather, uh, unhelpful error:

❯ excmd-parser master* ⟰  rm src/aST.ml; dune runtest
rm: src/aST.ml: No such file or directory
         ppx src/aST.pp.ml
    ocamldep src/.excmd_parser.objs/aST.pp.ml.d
    ocamlopt src/.excmd_parser.objs/excmd_parser__AST.{cmx,o} (exit 2)
(cd _build/default && /Users/ec/Sync/Code/excmd-parser/_opam/bin/ocamlopt.opt -w -40 -w -K -g -I src/.excmd_parser.objs -I src/.excmd_parser.objs/.private -I /Users/ec/Sync/Code/excmd-parser/_opam/lib/biniou -I /Users/ec/Sync/Code/excm
d-parser/_opam/lib/easy-format -I /Users/ec/Sync/Code/excmd-parser/_opam/lib/gen -I /Users/ec/Sync/Code/excmd-parser/_opam/lib/ocaml-migrate-parsetree -I /Users/ec/Sync/Code/excmd-parser/_opam/lib/ocaml/compiler-libs -I /Users/ec/Sync/
Code/excmd-parser/_opam/lib/ppx_deriving -I /Users/ec/Sync/Code/excmd-parser/_opam/lib/ppx_deriving_yojson -I /Users/ec/Sync/Code/excmd-parser/_opam/lib/ppx_tools_versioned -I /Users/ec/Sync/Code/excmd-parser/_opam/lib/result -I /Users
/ec/Sync/Code/excmd-parser/_opam/lib/sedlex -I /Users/ec/Sync/Code/excmd-parser/_opam/lib/uchar -I /Users/ec/Sync/Code/excmd-parser/_opam/lib/yojson -intf-suffix .ml -no-alias-deps -open Excmd_parser -o src/.excmd_parser.objs/excmd_par
ser__AST.cmx -c -impl src/aST.pp.ml)

File "src/aST.ml", line 14, characters 0-127:
Error: Unbound value poly_a

Presumably, the poly_a is supposed to be a 'a -> Yojson.Safe.json-type function to convert the polymorphic argument of the node GADT-type into a Yojson type? But I tried to include that argument in my custom located_to_yojson function, and I'm still getting that error … what'm I doing wrong?

whitequark commented 5 years ago

I don't think ppx_deriving_yojson supports GADTs, but also I think your code should work. It seems to be a bug.

ELLIOTTCABLE commented 5 years ago

Christ @whitequark, a minute and a quarter — that's gotta be some sort of new record 🤣.

Okay! I think that's good news! Let me know if you need any help narrowing it down or reproducing it; my setup is really strange.

Random maybe-relevant numbers:

(The rest are in the linked repository's opam-lockfile.)

whitequark commented 5 years ago

Unfortunately I haven't touched any of my OCaml code in... probably close to two years at this point. Been doing other things.

varunpatro commented 5 years ago

Is there any update on this @whitequark?

How did you proceed from here @ELLIOTTCABLE?

whitequark commented 5 years ago

No, there isn't any update on this. Why would you expect any? I no longer work on any of this code myself.

gasche commented 5 years ago

To complement @whitequark answer: ideally we would indeed have support for some forms of GADTs (some subsets may be easier to handle than others, and some plugins may make this easier than others), but no one is working on this as far as I can tell. It's an interesting problem, so if there are any volunteers, please speak up :-)

ejgallego commented 5 years ago

I am certainly interested in having GADTs work better with deriving; but can't promise any work in the short term. See also https://github.com/janestreet/ppx_sexp_conv/issues/8

ELLIOTTCABLE commented 5 years ago

Also-see-also: ocaml-ppx/ppx_deriving#7.

This is unfortunate; my particular use-case is that Menhir's inspection API generates a GADT. Generating converters for that would be nice!

File "src/tokens.ml", line 24, characters 0-797:
Error: This pattern matches values of type bytes terminal
       but a pattern was expected which matches values of type unit terminal
       Type bytes is not compatible with type unit 
    23  type _ terminal = 
    24    | T_error : unit terminal
    25    | T_URL_START : (string) terminal
    ...
    44    | T_COLON : unit terminal
    45  [@@deriving to_yojson { optional = true }]

Edit: Didn't even realize this was my own Issue when commenting. Oops! 🤣