Version française
Home     About     Download     Resources     Contact us    
Browse thread
Instance variables can't be polymorphic?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jacques Garrigue <garrigue@m...>
Subject: Re: [Caml-list] Instance variables can't be polymorphic?
From: Zheng Li <zheng_li@users.sourceforge.net>

> Here is an example:
> 
> ----
> # class c = object
>    val iter = List.iter
> end;;
> class c : object val iter : ('a -> unit) -> 'a list -> unit end
> ----
> 
> Since iter is a instance variable, the type parameter 'a won't be 
> required to parameterize the type of the class, perfect!
> 
> But it's still not polymorphic.
> 
> ----
> # let o = object
>    inherit c
>    method do_sth = iter print_int []; iter print_string []
> end;;
> Characters 69-81:
>      method do_sth = iter print_int []; iter print_string []
>                                              ^^^^^^^^^^^^
> Error: This expression has type string -> unit but is here used with type
>           int -> unit
> ----
> 
> Is that reasonable?  The inference of class c is done before the 
> declaration of object o, and the type signature says it's polymorphic 
> (not a weak one '_a).

Actually it's polymorphic, but only at the level of inheritance.
You could define two objects inheriting from c, one using print_int,
and the other print_string, and this would work.

Due to functional update (i.e. {< iter = ... >}), object-level
polymorphism would have to be explicit, but as you pointed next, no
syntax is provided for explicitly polymorphic fields.

> Trying to declare the polymorphism explicitly as
> 
> --
> val iter : 'a. ('a -> unit) -> 'a list -> unit = List.iter
> -- 
> 
> won't work. This syntax is only allowed for methods.

Yes. It would be too difficult to add such a functionality, but what
kind of application do you have in mind?

> Given that I really want to use polymorphic functions this way: as 
> instance variable and accessible through inheritance, is there any 
> workaround or suggestions ?

The simplest way I see currently is to use a let defined field (i.e.,
before the object keyword, but then you can't access it after
inheritance), or to use a private method. What is your problem with a
private method? It should be more flexible.
Of course you can also define a record to wrap your polymorphic value.

       Jacques Garrigue