Version française
Home     About     Download     Resources     Contact us    
Browse thread
Benchmarks against imperative languages
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: David Powers <david@g...>
Subject: Re: [Caml-list] Looking for suggestions on self-referential object definitions
I had no idea you could reference types in variant definitions before 
the types were fully defined - mostly due to some failure at trying to 
define the type before I even opened the class definition for container. 
  That said, obviously you can, which is enormously helpful.  ;)

I assume (based on some simple experiments) that this will only work out 
using polymorphic variants.

-David

Jonathan Roewen wrote:
>> class virtual item =
>>   object (self)
>>     val mutable name = ""
>>
>>     method name = name
>>
>>     method set_name newname = name <- newname
>>   end
>> ;;
>>
>>
>> class weapon =
>>   object (self)
>>     inherit item
>>   end
>> ;;
>>
>>
>> class container =
>>   object (self)
>>     inherit item
>>
>>     val mutable items = []
>>
>>     method add newitem = items <- (newitem :: items)
>>
>>     method contents = items
>>
>>     method remove i = items <- List.filter (fun x -> x != i) items
>>
>>     method contents_to_string =
>>       let print_item i =
>>         match i with
>>           | `Weapon w -> Printf.sprintf "%s (weapon)" w#name
>>           | `Container c -> Printf.sprintf "%s (container) -
>> Containing:\n%s" c#name c#contents_to_string
>>       in
>>         List.map print_item items
>>
>>   end
>> ;;
> 
> First off, method contents_to_string has conflicting types to be
> recursive. Second, adding a type constraint to items should fix your
> problems.
> 
> My changes:
> 
> class container =
>   .....
>     val mutable items : [ `Weapon of weapon | `Container of container
> ] list = []
>   ...
>     method contents_to_string =
>        .....
>         List.fold_left (fun a b -> if a = "" then print_item b else a
> ^ "; " ^ print_item b) "" items
> 
>   end
> ;;
> 
> Jonathan