Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] Managing a polymorphic environment
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ 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