Version française
Home     About     Download     Resources     Contact us    
Browse thread
Why can't I call a function over a subclass?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Martin Jambon <martin.jambon@e...>
Subject: Re: [Caml-list] Re: Why can't I call a function over a subclass?
On Fri, 5 Oct 2007, Luca de Alfaro wrote:

> But the larger issue is: when a type is used for an input parameters, as the
> type p in:
> f : int -> p -> bool
> why does the compiler have to complain that p has too many methods?

That's your point of view. The compiler complains about different types, 
but it doesn't know which one is intended:  does one object have 
too many methods or does the other object miss some methods?

With some experience, you will learn that artificially annotating types 
of objects or polymorphic variants leads to much clearer and earlier error 
messages.

So I would say that using ":>" is a rather mild annoyance, except that you 
have to learn what it means.


Martin


> Would it not be possible to make the type checker smarter, and ensure that
> when p is an input type, it is ok to have more methods?
> And for output types as well, it would seem?
> In other words, what is that fundamentally breaks if one were to change the
> ocaml type checker in this way?
>
> Luca
>
> On 10/5/07, Edgar Friendly <thelema314@gmail.com> wrote:
>>
>> Luca de Alfaro wrote:
>>> Yes, here is some code.  Any help would be very much appreciated.
>>> The following fails to type check:
>>>
>>> class p (x: int) = object
>>>   method plus1 : int = x + 1
>>> end
>>>
>>> class p2 (x: int) = object
>>>   inherit p x
>>>   method plus2 : int = x + 2
>>> end
>>>
>>> class r = object (self)
>>>   val mutable l = []
>>>   method make_el x = new p x
>>>   method add (x: int) : unit = l <- (self#make_el x) :: l
>>>   method length : int = List.length l
>>>   method total : int = List.fold_left (fun t el -> t + el#plus1) 0 l
>>> end
>>>
>>> class r2 = object
>>>   inherit r
>>>   method make_el x = new p2 x
>>>   method total2 : int = List.fold_left (fun t el -> t + el#plus2) 0 l
>>> end
>>>
>> if I manually perform the inherit operation by pasting the code from r1
>> into r2, I get:
>>
>> class r2 = object (self)
>>   val mutable l = []
>>   method make_el x = new p2 x
>>   method add (x: int) : unit = l <- (self#make_el x) :: l
>>   method length : int = List.length l
>>   method total2 : int = List.fold_left (fun t el -> t + el#plus2) 0 l
>> end
>>
>> which compiles just fine, and probably works as intended.  If I include
>> the original method make_el above the new one like this:
>>   method make_el x = new p x
>>   method make_el x = new p2 x
>> Ignoring the warning about overriding methods within the same class, we
>> come to the root of the type problem: make_el must have a type.  After
>> inference completes on the first line, make_el's type is determined to
>> be p.  The second make_el's type must match, but it doesn't.  I don't
>> see a solution for your problem that doesn't involve this kind of manual
>> expansion and removal of duplicate methods, but I'm fairly sure this is
>> the real problem for you.
>>
>> E.
>>
>

--
http://martin.jambon.free.fr