From: Guillaume Yziquel <guillaume.yziquel@citycable.ch>
To: caml-list@inria.fr
Cc: "Daniel Bünzli" <daniel.buenzli@erratique.ch>
Subject: Obj.magic and existential types.
Date: Fri, 19 Jun 2009 19:42:50 +0200 [thread overview]
Message-ID: <4A3BCE1A.3010403@citycable.ch> (raw)
Hello.
Please don't scream: I've been using Obj.magic...
But the result is rather interesting. It can record a flow of
computations, and recompute them only when upstream data has been modified:
> # let (n', n) = Dependent.encapsulate 1;;
> val n' : int Dependent.data = <abstr>
> val n : int Dependent.t = <abstr>
> # let (_, next) = Dependent.encapsulate (fun x -> x + 1);;
> val next : (int -> int) Dependent.t = <abstr>
> # let m = Dependent.apply next n;;
> val m : int Dependent.t = <abstr>
> # Dependent.access m;;
> - : int = 2
> # Dependent.set n' 3;;
> - : unit = ()
> # Dependent.access m;;
> - : int = 4
The piece of code responsible for this behaviour is at the end of the
message.
I learnt that I could perhaps overcome the use of Obj.magic by using
existential types. I was advised to read the following post on this topic:
http://caml.inria.fr/pub/ml-archives/caml-list/2004/01/52732867110697f55650778d883ae5e9.en.html
However, I do not really understand how Daniel implemented existential
types there, and I do not really see how it can be adapted to my code.
Suggestions welcomed.
Here's the code, rather disorganised at the moment.
All the best,
Guillaume Yziquel.
> type read;;
> type write;;
>
> type 'a computation = (Obj.t -> 'a) t * Obj.t t
>
> and ('a, 'b) aux_t = Dependent of
> ( 'a option ref *
> 'a computation option *
> Obj.t t list ref)
>
> and 'a data = ('a, write) aux_t
> and 'a t = ('a, read) aux_t;;
>
> let encapsulate (x : 'a) : ('a data) * ('a t) =
> let z = Dependent ((ref (Some x)), None, (ref [])) in (z, z);;
>
> let add_dependency (alpha : 'a t) (beta : 'b t) =
> let Dependent (_, _, dep) = alpha in
> dep := ((Obj.magic beta) : Obj.t t)::!dep;;
>
> let apply (f : ('b -> 'a) t) (x : 'b t) : 'a t =
> let computation : 'a computation =
> ((Obj.magic f) : (Obj.t -> 'a) t),
> ((Obj.magic x) : Obj.t t) in
> let f_x : 'a t = Dependent (
> ((ref None) : 'a option ref),
> ((Some computation) : 'a computation option),
> ((ref []) : Obj.t t list ref)) in
> add_dependency f f_x;
> add_dependency x f_x;
> f_x;;
>
> exception Undefined;;
>
> module rec Aux :
> sig
>
> val access : 'a t -> 'a
> val update : 'a t -> ('b -> 'a) t -> 'b t -> 'a
> val reset : 'a t -> unit
>
> end = struct
>
> let rec access y =
> let Dependent (opt_ref_x, comp_opt, _) = y in
> match !opt_ref_x with | Some x -> x | None ->
> begin match comp_opt with
> | None -> raise Undefined
> | Some (fun_t, arg_t) -> Aux.update y fun_t arg_t
> end
>
> and update y fun_t arg_t =
> let Dependent (opt_ref_x, _, dependencies) = y in
> List.iter Aux.reset !dependencies;
> let result = (Aux.access fun_t) (Aux.access arg_t) in
> opt_ref_x := Some result; result
>
> and reset z =
> let Dependent (opt_ref_x, _, dependencies) = z in
> match !opt_ref_x with
> | None -> () | Some _ -> begin
> opt_ref_x := None;
> List.iter Aux.reset !dependencies
> end;;
>
> end;;
>
> include Aux;;
>
> exception Flawed_implementation;;
>
> let set (x : 'a data) (v : 'a) : unit =
> let Dependent (opt_ref_x, comp_opt, dependencies) = x in
> match comp_opt with | Some _ -> raise Flawed_implementation | None ->
> begin List.iter Aux.reset !dependencies;
> opt_ref_x := Some v
> end;;
--
Guillaume Yziquel
http://yziquel.homelinux.org/
next reply other threads:[~2009-06-19 17:46 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-19 17:42 Guillaume Yziquel [this message]
2009-06-19 18:21 ` Daniel Bünzli
2009-06-19 18:30 ` Guillaume Yziquel
2009-06-19 18:37 ` Daniel Bünzli
2009-06-19 18:47 ` [Caml-list] " Jake Donham
2009-06-20 8:30 ` Daniel Bünzli
2009-06-21 18:08 ` Jake Donham
2009-06-21 18:39 ` Yaron Minsky
2009-06-22 0:03 ` Daniel Bünzli
2009-06-22 9:19 ` Benjamin Canou
2009-06-22 17:02 ` Jake Donham
2009-06-23 0:24 ` Daniel Bünzli
2009-06-23 0:34 ` Jake Donham
2009-06-23 2:22 ` Jake Donham
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=4A3BCE1A.3010403@citycable.ch \
--to=guillaume.yziquel@citycable.ch \
--cc=caml-list@inria.fr \
--cc=daniel.buenzli@erratique.ch \
/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