janestreet / ppx_sexp_conv

Generation of S-expression conversion functions from type definitions
MIT License
88 stars 17 forks source link

GADT support #8

Closed ejgallego closed 4 years ago

ejgallego commented 8 years ago

Dear ppx_sexp_conv devs,

thanks again for this great tool, it would be great if GADTs could be serialized both ways. This:

type _ obj =
  | OInt :    int obj
  | OStr : string obj
[@@deriving of_sexp]

currently results in:

Error: This expression has type int obj
       but an expression was expected of type v_x__001_ obj
       Type int is not compatible with type v_x__001_ 

Note that [@@deriving sexp_of] works fine and it indeed is very useful!

ghost commented 8 years ago

Unfortunately it's not possible to write such a function as it would be unsafe. Instead you need to wrap the type into a GADT to introduce the existential:

type packed_obj = Obj : _ obj -> packed_obj

Currently there is no special support in findlib for types that are wrapped in such a way. What we usually do is define a helper type:

module For_sexp = struct
  type t = OInt | OStr [@@deriving of_sexp]
end

type _ t = OInt : int t | OStr : string t

type packed = T : _ t -> packed

let packed_of_sexp sexp =
  match For_sexp.t_of_sexp with
  | OInt -> T OInt
  | OStr -> T OStr
ejgallego commented 8 years ago

Oh indeed, I see!

Thank you very much for the reply @diml .

aalekseyev commented 4 years ago

I'm closing this issue because the specific question got answered. The general support of GADTs is a complicated topic and definitely not fully explored. Any proposals for how to support GADTs are welcome in separate issues.