Browse thread
[Caml-list] Managing a polymorphic environment
-
Diego Olivier Fernandez Pons
- Jean-Baptiste Rouquier
-
brogoff
- Diego Olivier Fernandez Pons
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Diego Olivier Fernandez Pons <Diego.FERNANDEZ_PONS@e...> |
| Subject: | Re: [Caml-list] Managing a polymorphic environment |
Bonjour,
> I'm sure I'm completely misunderstanding your problem, but how about
> referring to the environment variables by by strings and attaching
> properties to them, using the property list trick that Xavier
> described here a few years ago
What I had in mind is basing the environment in the polymorphic
physical equality (==) - and therefor I said the environment was
expected to be small and hence could use an equality based set
representation
module Env = struct
type 'a t = ('a * string) list
let empty : 'a t = []
let add : 'a -> string -> 'a t -> 'a t = fun x s l -> (x, s) :: l
let rec get_string : 'a -> 'a t -> string = fun x l ->
match l with
| [] -> ""
| (y, s) :: tail -> if x == y then s else get_string x tail
end
# let env = Env.empty;;
val env : 'a Env.t = []
# let x = 5;;
val x : int = 5
# let y = 3;;
val y : int = 3
# let env = Env.add x "x" env;;
val env : int Env.t = [(5, "x")]
# let env = Env.add y "y" env;;
val env : int Env.t = [(3, "y"); (5, "x")]
# Env.get_string x env;;
- : string = "x"
# Env.get_string y env;;
- : string = "y"
The problem is to make Env forget it is typed because the
polymorphic parameter 'a captures the first instanciated type
(int in my example) even if (==) is polymorphic.
I solve it below with some magic.
My code seems - at least to me - correctly typed. Why isn't 'a Env.t
'totally' polymorphic or is it polymorphic in a 'more general' sense ?
It does not seem able to raise a runtime error, does it ?
module Env = struct
type t
let empty : t = Obj.magic []
let add : 'a -> string -> t -> t = fun x s l ->
let l' : ('a * string) list = Obj.magic l in
let l'' = (x, s) :: l' in
let l''' : t = Obj.magic l'' in
l'''
let rec get_string : 'a -> t -> string = fun x l ->
let l' : ('a * string) list = Obj.magic l in
match l' with
| [] -> ""
| (y, s) :: _ when x == y -> s
| _ :: tail ->
let tail' : t = Obj.magic tail in
get_string x tail'
end
module Env :
sig
type t
val empty : t
val add : 'a -> string -> t -> t
val get_string : 'a -> t -> string
end
Example :
# let env = Env.empty;;
val env : Env.t = <abstr>
# let x = 5;;
val x : int = 5
# let y = 3.0;;
val y : float = 3.
# let env = Env.add x "an int" env;;
val env : Env.t = <abstr>
# let env = Env.add y "a float" env;;
val env : Env.t = <abstr>
# Env.get_string x env;;
- : string = "an int"
# Env.get_string y env;;
- : string = "a float"
Diego Olivier
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners