From: Rodolphe Lepigre <rodolphe.lepigre@univ-savoie.fr>
To: Trevor Smith <trevorsummerssmith@gmail.com>
Cc: "caml-list@inria.fr" <caml-list@inria.fr>
Subject: Re: [Caml-list] GADTs and JSON
Date: Thu, 21 May 2015 20:44:04 +0200 [thread overview]
Message-ID: <20150521184404.GA598@HPArchRod> (raw)
In-Reply-To: <CAG-KTt_Um5B263zK3M6Y7on62-F0rrkb-1MpcRtMqTH6tLRDjQ@mail.gmail.com>
Hi,
> Is it possible to encode a recursive, heterogenous map and list datastructure
> with GADTs?
>
> I want to encode JSON (there are already a couple of great libraries out there
> so this is kind of an academic question). I would like to have functions that
> can only take a JSON map type, for example to take a json map and return a
> value. The key here is that the map can hold values of type int,string and also
> maps. Is this possible?
>
> eg get : (map : map json) -> key:string -> 'a json
>
> Thank you.
>
> Trevor
You should probably have a look at the examples given for GADTs on the page
about language extensions (advanced examples section):
http://caml.inria.fr/pub/docs/manual-ocaml-400/manual021.html#toc85
Not so long ago I used equality types to encode collections of object of
different types. Here is an example with lists and a function for obtaining
the n-th element.
##########
type (_,_) eq = Eq : ('a,'a) eq
type 'a typ =
| Int : int typ
| Float : float typ
| Pair : 'a typ * 'b typ -> ('a * 'b) typ
let rec equal : type a b. a typ -> b typ -> (a,b) eq option = fun t1 t2 ->
match (t1,t2) with
| (Int , Int ) -> Some Eq
| (Float , Float ) -> Some Eq
| (Pair(a,b) , Pair(c,d)) ->
begin
match (equal a c, equal b d) with
| (Some Eq, Some Eq) -> Some Eq
| _ -> None
end
| _ -> None
type _ tlist' =
| Nil : unit tlist'
| Cons : ('a typ * 'a * unit tlist') -> unit tlist'
type tlist = unit tlist'
let rec nth : type a. tlist -> int -> a typ -> a = fun l n ty ->
match (l, n) with
| (Nil , _) -> raise Not_found
| (Cons(ty',t,_), 0) ->
begin
match equal ty ty' with
| Some Eq -> t
| None -> invalid_arg "Ill type in nth"
end
| (Cons(_,_,l) , _) -> nth l (n-1) ty
let l = Cons(Int, 3, Cons(Float, 4.2, Nil))
let n : int = nth l 0 Int
let f : float = nth l 1 Float
##########
Regards,
Rodolphe
--
Rodolphe Lepigre
LAMA, Université de Savoie, FRANCE
http://lama.univ-savoie.fr/~lepigre/
prev parent reply other threads:[~2015-05-21 18:44 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-21 16:42 Trevor Smith
2015-05-21 16:59 ` Milan Stanojević
2015-05-21 18:44 ` Rodolphe Lepigre [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150521184404.GA598@HPArchRod \
--to=rodolphe.lepigre@univ-savoie.fr \
--cc=caml-list@inria.fr \
--cc=trevorsummerssmith@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox