├── META ├── Makefile ├── mixtbl.ml ├── mixtbl.mli └── README.md /META: -------------------------------------------------------------------------------- 1 | version = "0.0.0" 2 | archive(byte) = "mixtbl.cmo" 3 | archive(native) = "mixtbl.cmx" 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default all opt install uninstall reinstall clean 2 | default: all opt 3 | all: 4 | ocamlc -c -g mixtbl.mli 5 | ocamlc -c -g mixtbl.ml 6 | opt: 7 | ocamlopt -c -g mixtbl.mli 8 | ocamlopt -c -g mixtbl.ml 9 | clean: 10 | rm -f *~ *.cm[iox] *.o 11 | install: 12 | ocamlfind install mixtbl META *.mli *.ml *.cm[iox] *.o 13 | uninstall: 14 | ocamlfind remove mixtbl 15 | reinstall: 16 | -$(MAKE) uninstall 17 | $(MAKE) install 18 | -------------------------------------------------------------------------------- /mixtbl.ml: -------------------------------------------------------------------------------- 1 | (* This source code is released into the Public Domain *) 2 | 3 | type 'a t = ('a, (unit -> unit)) Hashtbl.t 4 | 5 | let create n = Hashtbl.create n 6 | 7 | let access () = 8 | let r = ref None in 9 | let get tbl k = 10 | r := None; (* reset state in case last operation was not a get *) 11 | try 12 | (Hashtbl.find tbl k) (); 13 | let result = !r in 14 | r := None; (* clean up here in order to avoid memory leak *) 15 | result 16 | with Not_found -> None 17 | in 18 | let set tbl k v = 19 | let v_opt = Some v in 20 | Hashtbl.replace tbl k (fun () -> r := v_opt) 21 | in 22 | get, set 23 | -------------------------------------------------------------------------------- /mixtbl.mli: -------------------------------------------------------------------------------- 1 | (* This source code is released into the Public Domain *) 2 | 3 | type 'a t 4 | (** A hash table containing values of different types. 5 | The type parameter ['a] represents the type of the keys. *) 6 | 7 | val create : int -> 'a t 8 | (** [create n] creates a hash table of initial size [n]. *) 9 | 10 | val access : unit -> ('a t -> 'a -> 'b option) * ('a t -> 'a -> 'b -> unit) 11 | (** 12 | Return a pair (get, set) that works for a given type of values. 13 | This function is normally called once for each type of value. 14 | Several getter/setter pairs may be created for the same type, 15 | but a value set with a given setter can only be retrieved with 16 | the matching getter. 17 | The same getters and setters may be reused across multiple tables. 18 | *) 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Toy OCaml implementation of a statically-typed hash table holding values 2 | of different types. 3 | 4 | For actual use, you probably want to include a number of functions from 5 | the standard Hashtbl module and a way to iterate over the keys. 6 | 7 | Demo: 8 | ```ocaml 9 | $ ocaml 10 | OCaml version 4.00.1 11 | 12 | # #use "topfind";; 13 | - : unit = () 14 | Findlib has been successfully loaded. Additional directives: 15 | #require "package";; to load a package 16 | #list;; to list the available packages 17 | #camlp4o;; to load camlp4 (standard syntax) 18 | #camlp4r;; to load camlp4 (revised syntax) 19 | #predicates "p,q,...";; to set these predicates 20 | Topfind.reset();; to force that packages will be reloaded 21 | #thread;; to enable threads 22 | 23 | - : unit = () 24 | # #require "mixtbl";; 25 | /home/martin/dev/mn/powder/lib/ocaml/site-lib/mixtbl: added to search path 26 | /home/martin/dev/mn/powder/lib/ocaml/site-lib/mixtbl/mixtbl.cmo: loaded 27 | # let get_int, set_int = Mixtbl.access ();; 28 | val get_int : '_a Mixtbl.t -> '_a -> '_b option = 29 | val set_int : '_a Mixtbl.t -> '_a -> '_b -> unit = 30 | # let tbl = Mixtbl.create 10;; 31 | val tbl : '_a Mixtbl.t = 32 | # get_int tbl "a";; 33 | - : '_a option = None 34 | # set_int tbl "a" 1;; 35 | - : unit = () 36 | # get_int tbl "a";; 37 | - : int option = Some 1 38 | # let get_string, set_string = Mixtbl.access ();; 39 | val get_string : '_a Mixtbl.t -> '_a -> '_b option = 40 | val set_string : '_a Mixtbl.t -> '_a -> '_b -> unit = 41 | # set_string tbl "b" "Hello";; 42 | - : unit = () 43 | # get_string tbl "b";; 44 | - : string option = Some "Hello" 45 | # get_string tbl "a";; 46 | - : string option = None 47 | # get_int tbl "a";; 48 | - : int option = Some 1 49 | # set_string tbl "a" "Bye";; 50 | - : unit = () 51 | # get_int tbl "a";; 52 | - : int option = None 53 | # get_string tbl "a";; 54 | - : string option = Some "Bye" 55 | ``` 56 | --------------------------------------------------------------------------------