caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Subclasses and pattern matching
@ 2003-09-19 14:21 katre
  2003-09-19 14:52 ` Richard Jones
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: katre @ 2003-09-19 14:21 UTC (permalink / raw)
  To: caml-list

Hello again!

I'm working on a project where I want to create a list of data, which is
all similar but not identical.  In other languages with which I am
familiar, I would do this with a base class and a few subclasses, as
such:

class virtual abstractClass = 
    object

    method virtual to_string : unit -> string
end

class subclass1 = 
    object
    inherit abstractClass

    method thing () = "subclass1 thing"
    method to_string () = "subclass 1"
end

class subclass2 = 
    object
    inherit abstractClass

    method thing2 () = "subclass2 thing"
    method to_string () = "subclass 2"
end

And I would create the list as

let l = [ (new subclass1 :> abstractClass); (new subclass :> abstractClass); (new subclass1 :> abstractClass); (new subclass2 :> abstractClass) ];

This seems to work fine.

However, I want to use pattern matching to go over this list.  I'm not
sure how this would work in ocaml.  My ideal function would look
something like this:

let rec show_list l =
    match l with
        [] -> ()
        | (h ofclass subclass1)::t -> print_string (h#thing()); show_list t
        | (h ofclass subclass2)::t -> print_string (h#thing2()); show_list t
        | (h ofclass abstractClass)::t -> print_string ("Unknown object " ^ (h#to_string())); show_list t


Is this possible?  What would the syntax be?

katre

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Subclasses and pattern matching
  2003-09-19 14:21 [Caml-list] Subclasses and pattern matching katre
@ 2003-09-19 14:52 ` Richard Jones
  2003-09-19 15:22   ` katre
  2003-09-19 16:40 ` Claude Marche
  2003-09-20 15:00 ` Michal Moskal
  2 siblings, 1 reply; 7+ messages in thread
From: Richard Jones @ 2003-09-19 14:52 UTC (permalink / raw)
  To: katre; +Cc: caml-list


Possibly I'm being dumb here, but wouldn't it be better to use
a union type, eg:

type num = Int of int | Float of float

type list_of_nums = num list

let print_num = function
    Int i -> print_endline (string_of_int i)
  | Float f -> print_endline (string_of_float f)

let print_nums = List.iter print_num

Rich.

-- 
Richard Jones. http://www.annexia.org/ http://freshmeat.net/users/rwmj
Merjis Ltd. http://www.merjis.com/ - all your business data are belong to you.
C2LIB is a library of basic Perl/STL-like types for C. Vectors, hashes,
trees, string funcs, pool allocator: http://www.annexia.org/freeware/c2lib/

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Subclasses and pattern matching
  2003-09-19 14:52 ` Richard Jones
@ 2003-09-19 15:22   ` katre
  2003-09-19 15:58     ` art yerkes
  0 siblings, 1 reply; 7+ messages in thread
From: katre @ 2003-09-19 15:22 UTC (permalink / raw)
  To: Richard Jones; +Cc: caml-list

Richard Jones wrote:
> 
> Possibly I'm being dumb here, but wouldn't it be better to use
> a union type, eg:
> 
> type num = Int of int | Float of float
> 

Yes, except for two facts:

a) Each different type has different data available (some are ints, some
strings, some more complex)
b) Each different type has a lot of data.  I don't really want to
specify a 10-member tuple for each constructor :)
c) Where the data is used, I want to match two or three different types,
and then call a default method with anything left over.  With a union, I
have to deal with every possible type, or do nothing with the data.

To clarify, using your type above, I can't do

match n with
    Int(i) -> print_int i
    | _ -> print_int some_data_from_n

Remember, all of my structures have many more than 1 piece of data.  A
class inheritance really is the best way to model the data structure, I
just want to be able to pattern match on it.

katre

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Subclasses and pattern matching
  2003-09-19 15:22   ` katre
@ 2003-09-19 15:58     ` art yerkes
       [not found]       ` <20030919155431.GA31387@henchmonkey.org>
  0 siblings, 1 reply; 7+ messages in thread
From: art yerkes @ 2003-09-19 15:58 UTC (permalink / raw)
  To: caml-list

On Fri, 19 Sep 2003 11:22:52 -0400
katre <katre@henchmonkey.org> wrote:

> Richard Jones wrote:
> > 
> > Possibly I'm being dumb here, but wouldn't it be better to use
> > a union type, eg:
> > 
> > type num = Int of int | Float of float
> > 
> 
> Yes, except for two facts:
> 
> a) Each different type has different data available (some are ints, some
> strings, some more complex)
> b) Each different type has a lot of data.  I don't really want to
> specify a 10-member tuple for each constructor :)
> c) Where the data is used, I want to match two or three different types,
> and then call a default method with anything left over.  With a union, I
> have to deal with every possible type, or do nothing with the data.
> 
> To clarify, using your type above, I can't do
> 
> match n with
>     Int(i) -> print_int i
>     | _ -> print_int some_data_from_n
> 
> Remember, all of my structures have many more than 1 piece of data.  A
> class inheritance really is the best way to model the data structure, I
> just want to be able to pattern match on it.
> 
> katre
> 

You could wrap your items in a union:

exception NoExternalRepForBase

type 'a base_extern_t = 
        Derived1 of 'a | Derived2 of 'a

class virtual base =
object
	method virtual as_external : unit -> base base_extern_t
end

class derived1 =
object(self)
	inherit base
	method as_external () = Derived1 (self :> base)
end

class derived2 =
object(self)
	inherit base
	method as_external () = Derived2 (self :> base)
end

let l = [ (new derived2 # as_external()) ; (new derived1 # as_external()) ]
-- 
"Should array indices start at 0 or 1? My compromise of 0.5 was rejected
 without, I thought, proper consideration."
   - S. Kelly-Bootle

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Subclasses and pattern matching
       [not found]       ` <20030919155431.GA31387@henchmonkey.org>
@ 2003-09-19 16:32         ` art yerkes
  0 siblings, 0 replies; 7+ messages in thread
From: art yerkes @ 2003-09-19 16:32 UTC (permalink / raw)
  To: caml-list

On Fri, 19 Sep 2003 11:54:31 -0400
katre <katre@henchmonkey.org> wrote:

> art yerkes wrote:
> > You could wrap your items in a union:
> > 
> > exception NoExternalRepForBase
> > 
> > type 'a base_extern_t = 
> >         Derived1 of 'a | Derived2 of 'a
> > 
> > class virtual base =
> > object
> > 	method virtual as_external : unit -> base base_extern_t
> > end
> > 
> 
> Will this allow me to call methods that only exist on the derived
> classes after the pattern match?  I'm not sure this type lets the
> typechecker know exactly which derived class I have.
> 
> katre

I've heard that coca-ml does the rest (though I haven't tried it myself).

http://www.pps.jussieu.fr/~emmanuel/Public/Dev/coca-ml/index-en.html

-- 
"Should array indices start at 0 or 1? My compromise of 0.5 was rejected
 without, I thought, proper consideration."
   - S. Kelly-Bootle

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Subclasses and pattern matching
  2003-09-19 14:21 [Caml-list] Subclasses and pattern matching katre
  2003-09-19 14:52 ` Richard Jones
@ 2003-09-19 16:40 ` Claude Marche
  2003-09-20 15:00 ` Michal Moskal
  2 siblings, 0 replies; 7+ messages in thread
From: Claude Marche @ 2003-09-19 16:40 UTC (permalink / raw)
  To: katre; +Cc: caml-list


>>>>> "katre" == katre  <katre@henchmonkey.org> writes:

    katre> Hello again!
    katre> I'm working on a project where I want to create a list of data, which is
    katre> all similar but not identical.  In other languages with which I am
    katre> familiar, I would do this with a base class and a few subclasses, as
    katre> such:

    katre> [...]

    katre> However, I want to use pattern matching to go over this list.  I'm not
    katre> sure how this would work in ocaml.  My ideal function would look
    katre> something like this:

    katre> let rec show_list l =
    katre>     match l with
    katre>         [] -> ()
    katre>         | (h ofclass subclass1)::t -> print_string (h#thing()); show_list t
    katre>         | (h ofclass subclass2)::t -> print_string (h#thing2()); show_list t
    katre>         | (h ofclass abstractClass)::t -> print_string ("Unknown object " ^ (h#to_string())); show_list t


    katre> Is this possible?  What would the syntax be?

You have to choose between using a union type and then
program with pattern matching, or choose classes and then use
inheritance. In your case, with classes :


class virtual abstractClass = 
    object
    method virtual to_string : unit -> string
    method virtual thing : unit -> string
end

class subclass1 = 
    object
    inherit abstractClass
    val i = 0
    method thing () = "I'm an integer whose value is " ^ (string_of_int i)
    method to_string () = "subclass 1"
end

class subclass2 = 
    object
    inherit abstractClass
    val v = 1.0
    method thing () =  "I'm an float whose value is " ^ (string_of_float v)
    method to_string () = "subclass 2"
end


let l = [ (new subclass1 :> abstractClass); (new subclass2 :> abstractClass) ]

let show_list =
  List.iter (fun o -> print_string (o#thing()));;

show_list l;;

Hope this helps,


-- 
| Claude Marché           | mailto:Claude.Marche@lri.fr |
| LRI - Bât. 490          | http://www.lri.fr/~marche/  |
| Université de Paris-Sud | phoneto: +33 1 69 15 64 85  |
| F-91405 ORSAY Cedex     | faxto: +33 1 69 15 65 86    |

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Subclasses and pattern matching
  2003-09-19 14:21 [Caml-list] Subclasses and pattern matching katre
  2003-09-19 14:52 ` Richard Jones
  2003-09-19 16:40 ` Claude Marche
@ 2003-09-20 15:00 ` Michal Moskal
  2 siblings, 0 replies; 7+ messages in thread
From: Michal Moskal @ 2003-09-20 15:00 UTC (permalink / raw)
  To: katre; +Cc: caml-list

On Fri, Sep 19, 2003 at 10:21:56AM -0400, katre wrote:
> Hello again!
> 
> I'm working on a project where I want to create a list of data, which is
> all similar but not identical.  In other languages with which I am
> familiar, I would do this with a base class and a few subclasses, as
> such:
> 
> class virtual abstractClass = 
>     object
> 
>     method virtual to_string : unit -> string
> end
> 
> class subclass1 = 
>     object
>     inherit abstractClass
> 
>     method thing () = "subclass1 thing"
>     method to_string () = "subclass 1"
> end
> 
> class subclass2 = 
>     object
>     inherit abstractClass
> 
>     method thing2 () = "subclass2 thing"
>     method to_string () = "subclass 2"
> end
> 
> And I would create the list as
> 
> let l = [ (new subclass1 :> abstractClass); (new subclass :> abstractClass); (new subclass1 :> abstractClass); (new subclass2 :> abstractClass) ];
> 
> This seems to work fine.

The best way that would allow _ -> ... thing is something like this:

type specific = Subclass1 of subclass1 | Subclass2 of subclass2 | ... |
SubclassN of subclassN

type data = abstractClass * specific

match l with
| (_, Subclass1 x) :: xs -> ... 
| (_, Subclass2 x) :: xs -> ...
| (x, _) :: xs -> ...

In general there are no runtime types in OCaml, you have to organize
them yourself.

-- 
: Michal Moskal :: http://www.kernel.pl/~malekith : GCS {C,UL}++++$ a? !tv
: When in doubt, use brute force. -- Ken Thompson : {E-,w}-- {b++,e}>+++ h

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2003-09-20 15:05 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-19 14:21 [Caml-list] Subclasses and pattern matching katre
2003-09-19 14:52 ` Richard Jones
2003-09-19 15:22   ` katre
2003-09-19 15:58     ` art yerkes
     [not found]       ` <20030919155431.GA31387@henchmonkey.org>
2003-09-19 16:32         ` art yerkes
2003-09-19 16:40 ` Claude Marche
2003-09-20 15:00 ` Michal Moskal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).