9 people like it.

Heterogeneous container

OCaml original here : http://eigenclass.org/R2/writings/heterogeneous-containers-in-ocaml

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
//#r "FSharp.PowerPack.dll";;

open System.Collections.Generic

type t = HashMultiMap<int, unit -> unit>

let create () : t = new HashMultiMap<_, _>(13,HashIdentity.Structural)

let new_id : unit -> int =
    let id = ref 0 in
      fun () -> incr id; !id

let new_property () =
    let id = new_id () in
    let v = ref None in

    let set (t:t) x =
        t.Replace(id, (fun () -> v := Some x)) in

    let get (t:t) =
        try
            (t.[id]) ();
            match !v with
                | Some x as s -> v := None; s
                | None -> None
        with | :? KeyNotFoundException -> None
    in
    (set, get)

let get t (set, get) = get t
let set t (set, get) x = set t x 

//-- usage example 

let name = new_property ()
let age = new_property ()

let table = create ()

set table name "J.R. Hacker"
set table age 3

let _name = get table name
let _age  = get table age
namespace System
namespace System.Collections
namespace System.Collections.Generic
type t = obj

Full name: Script.t
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
val create : unit -> t

Full name: Script.create
module HashIdentity

from Microsoft.FSharp.Collections
val Structural<'T (requires equality)> : IEqualityComparer<'T> (requires equality)

Full name: Microsoft.FSharp.Collections.HashIdentity.Structural
val new_id : (unit -> int)

Full name: Script.new_id
val id : int ref
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val incr : cell:int ref -> unit

Full name: Microsoft.FSharp.Core.Operators.incr
val new_property : unit -> ('a -> 'b -> 'c) * ('d -> 'e option)

Full name: Script.new_property
val id : int
val v : 'e option ref
union case Option.None: Option<'T>
val set : (t -> 'f -> 'g)
val t : t
val x : 'f
union case Option.Some: Value: 'T -> Option<'T>
val get : (t -> 'e option)
val x : 'e
val s : 'e option
Multiple items
type KeyNotFoundException =
  inherit SystemException
  new : unit -> KeyNotFoundException + 2 overloads

Full name: System.Collections.Generic.KeyNotFoundException

--------------------
KeyNotFoundException() : unit
KeyNotFoundException(message: string) : unit
KeyNotFoundException(message: string, innerException: exn) : unit
val get : t:'a -> set:'b * get:('a -> 'c) -> 'c

Full name: Script.get
val t : 'a
val set : 'b
val get : ('a -> 'c)
val set : t:'a -> set:('a -> 'b -> 'c) * get:'d -> x:'b -> 'c

Full name: Script.set
val set : ('a -> 'b -> 'c)
val get : 'd
val x : 'b
val name : (t -> string -> obj) * (t -> obj option)

Full name: Script.name
val age : (t -> int -> obj) * (t -> obj option)

Full name: Script.age
val table : t

Full name: Script.table
val _age : obj option

Full name: Script._age
Raw view Test code New version

More information

Link:http://fssnip.net/9Q
Posted:12 years ago
Author:Ademar Gonzalez
Tags: types , universal , heterogeneous , container