Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Pietro Abate <Pietro.Abate@anu.edu.au>
To: ocaml ml <caml-list@inria.fr>
Subject: [Caml-list] set of sets ...
Date: Sun, 24 Oct 2004 17:51:02 +1000	[thread overview]
Message-ID: <20041024075102.GA9493@pulp.anu.edu.au> (raw)

Hi all,
I'm trying to write an extensible data structure where I can add new
types with minimal effort, but I'm kinda stuck...

my goal is to have a mixed list as:

let a1 = (new set :> mixtype1 store);;
let a2 = new setofset;;
let a3 = (new intlist :> mixtype1 store);;
let l = [a1;a2;a3]

this doesn't work, but just to give you an idea...

this is my approach. Is there a better way of doing it ?

First I defined a virtual class and a couple of auxiliary types. The
mixtype should be user extensible and the ext_rep should give me a
uniform representation of all my objects in terms of lists.

type mixtype = [
    | `Int of int
]
;;

type 'el ext_rep =
    | El of 'el list
    | Cont of 'el ext_rep list
;;


class virtual ['mt] store =
    object(self : 'store)
        method virtual assign : 'store -> unit
        method virtual add : 'mt -> unit
        method virtual del : 'mt -> unit
        method virtual access : 'mt ext_rep
        method virtual copy : 'store
    end
;;

(* The first class is a int list and it's easy... *)

class intlist =
    object
        inherit [mixtype] store
        val mutable data = []

        method data = data
        method assign store = data <- store#data
        method add e = data <- e::data
        method del e = ()
        method access = El(data)
        method copy = {< data = data >}
    end
;;

(* now I want to have set of int: *)

module OriginalSet = Set

module Set = OriginalSet.Make (
        struct
            type t = mixtype
            let compare = compare
        end
);;
    
class set =
    object
        inherit [mixtype] store
        val mutable data = Set.empty

        method data = data
        method assign store = data <- store#data
        method add e = data <- Set.add e data
        method del e = ()
        method access = El(Set.elements data)
        method copy = {< data = data >}
    end
;;

(* now I want to extend my mixtype, add a new type to use the set of int
class and define a set of sets of ints... This should give a good deal
of flexibility as to add a new type I just need to subclass store and
add a new mixtype that is more general... *)

type mixtype1 = [
    |`Set of set
    |mixtype
];;

module SetofSet = OriginalSet.Make (
        struct
            type t = mixtype1
            let compare = compare
        end
);;

class setofset =
    object
        inherit [mixtype1] store
        val mutable data = SetofSet.empty

        method data = data
        method assign store = data <- store#data
        method add e = data <- SetofSet.add e data
        method del e = ()
        method access =
            Cont (
                List.map (function
                    |`Set e -> (e#access: mixtype ext_rep :> mixtype1 ext_rep)
                    |#mixtype -> failwith "wrong type"
                    ) (SetofSet.elements data)
                )
        method copy = {< data = data >}
    end
;;

(* so far, so good. Now I want to put these three objects in a list and downcast 
them to the store class (using mixtype1 that should be a super-type of mixtype) *)

(* I tried many combinations, but with poor results... this doesn't work ....
It says:
Type mixtype = [ `Int of int ] is not compatible with type
  'b = [> `Int of int | `Set of set ] 
The first variant type does not allow tag(s) `Set.
This simple coercion was not fully general. Consider using a double coercion.

But I don't understand why, as mixtype1 should be more general than mixtype...
*)

let a1 = (new set :> mixtype1 store);;
let a2 = new setofset;;
let a3 = (new intlist :> mixtype1 store);;

let l = [a1;a2;a3]

thanks,
p

-- 
++ "All great truths begin as blasphemies." -George Bernard Shaw
++ Please avoid sending me Word or PowerPoint attachments.
   See http://www.fsf.org/philosophy/no-word-attachments.html

-------------------
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


             reply	other threads:[~2004-10-24  7:52 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-10-24  7:51 Pietro Abate [this message]
2004-10-24 11:11 ` John Prevost

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=20041024075102.GA9493@pulp.anu.edu.au \
    --to=pietro.abate@anu.edu.au \
    --cc=caml-list@inria.fr \
    /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