(1) basic: “@default” is for fields, and you can’t use it on naked types (as in your second example). But I’m presuming you meant that as an example?
(2) more nuanced: [I tried this with pa_ppx’s version of the yojson deriver. It’s possible that the reason this failed is -different- from why the ppx yojson deriver failed, but also possible that it’s the same reason. In any case …]
$ cat foo.ml
type 'a t = { x : 'a [@default None] } [@@deriving yojson]
$ not-ocamlfind ocamlc -package pa_ppx.deriving_plugins.yojson,camlp5.pr_o -syntax camlp5o -c foo.ml
File "/tmp/ocamlpp309388", line 11, characters 21-25:
Error: This expression has type 'a option
but an expression was expected of type a
So the problem here is that the deriver expects the type to be 'a t but instead it gets 'b option t When I was implementing these type-derivers, I looked at the PPX versions, and they all put in various type-coercions to ensure that generated code had the right types. If for no other reason, than that it was necessary to get generated code to work right for polymorphic variants.
Maybe that’s not what’s happening with the PPX yojson deriver.
ETA: and in case it’s useful, here’s the code the deriver generated (though the code of course didn’t compile):
type 'a t = { x : 'a[@default None] }[@@deriving_inline of_yojson]
let rec of_yojson : 'a .
(Yojson.Safe.t -> ('a, string) Rresult.result) -> Yojson.Safe.t ->
('a t, string) Rresult.result =
fun (type a) (tp_0 : Yojson.Safe.t -> (a, string) Rresult.result) arg ->
(let open! Pa_ppx_runtime.Runtime in
let open! Stdlib in
function
`Assoc xs ->
let rec loop xs v_x =
match xs with
("x", v_x) :: xs -> loop xs (tp_0 v_x)
| [] -> Rresult.R.bind v_x (fun v_x -> Result.Ok {x = v_x})
| _ :: xs -> loop xs v_x
in
loop xs (Result.Ok None)
| _ -> Result.Error "Foo.t")
arg
[@@@end]