cconv icon indicating copy to clipboard operation
cconv copied to clipboard

Encoder / decoder for multiple value types

Open prepor opened this issue 9 years ago • 7 comments

Hello. I'm confused and can't understand how I can create encoder / decoder for types which are multiple value types. Concrete example is To.ml [https://github.com/mackwic/To.ml/]

https://github.com/mackwic/To.ml/blob/master/src/tomlTypes.ml#L58

This types mirror Toml specification where arrays can contain only one type. Can you give me the cue to how to write encoder for these types?

prepor avatar Sep 27 '16 06:09 prepor

You mean sum types? See the module Lambda in example/all.ml, there are combinators sum and sum_fix precisely for that.

edit: if it's for an encoder/decoder of toml, you can look at the bencode encoder (which is also a sum type! Actually they all are. Give a look to the current encoders)

c-cube avatar Sep 27 '16 07:09 c-cube

No. Let see at encoder:

list should be encoded as

type array =
  | NodeEmpty
  | NodeBool of bool list
  | NodeInt of int list
  | NodeFloat of float list
  | NodeString of string list
  | NodeDate of float list
  | NodeArray of array list (* this can have any type *)
  | NodeTable of table list

but list accepts 'a list, where 'a is common type for all values.

prepor avatar Sep 27 '16 07:09 prepor

I'm trying to describe output for toml types

prepor avatar Sep 27 '16 07:09 prepor

Yes I see, that's interesting indeed. I didn't think of that case because usually, people use polymorphism ^^.

The first thing I can think of, would be to write an intermediate polymorphic AST for encoding (not decoding), and then to convert this into TOML.

type poly_array = poly_value list
and poly_value =
  | Empty | Bool of bool | Int of int | Array of poly_array | … 

(* write encoder to poly_array/poly_value, which uses `NodeArray` for heterogeneous
   arrays, or monomorphic versions otherwise *)

let rec convert_value (v:poly_value): TomlTypes.array = …
and convert_array (a:poly_array): TomlTypes.array = …

(* use `map` to convert to array then to TomlValues.array *)

c-cube avatar Sep 27 '16 07:09 c-cube

usually, people use polymorphism ^^.

Usually, serialisation formats are more flexible than toml. But toml mirrors rust's type system.

But this is impossible to use such technic with encoders generated by ppx, isn't it?

prepor avatar Sep 27 '16 07:09 prepor

I suppose a ppx_deriving_toml would indeed have the same issue, at least if it tried to provide polymorphic encoders. It could match monomorphic types ("if ty=int list then ... else if ty = string list" etc.) but in general toml is not powerful enough, unless you always encode to NodeArray. Anyway, here, output is the hard part…

c-cube avatar Sep 27 '16 07:09 c-cube

I made workaround https://github.com/prepor/To.ml/blob/ed768ab9c8077256773c1e14dd6c178134a7ed4c/cconv/tomlCconv.ml#L1

But its ugly and inefficient :(

prepor avatar Sep 27 '16 10:09 prepor