Hi Guillaume,

You need to use either records or objects to pass a polymorphic argument
(note that the type you want for print_both is ('a. 'a -> 'a) -> unit, not 'a. ('a -> 'a) -> unit).

For example, with objects you could do:

  let print_both (o : <f: 'a. 'a -> a>) =
    print_int (o # f 1);
    print_float (o # f 1.0)

Best wishes,
Nicolas


On Mon, May 16, 2016 at 5:45 PM, Guillaume Hennequin <g.hennequin@eng.cam.ac.uk> wrote:
Dear caml-list,

let id x = x

is polymorphic, and indeed I can apply it to various types:

let _ = print_float (id 1.)
let _ = print_int (id 1)

Now, say you want to write a function that takes a function of the same ['a->'a] type as [id] above, and applies it to two different types:

let print_both f =
 print_int (f 1);
 print_float (f 1.0)

That in fact won't compile:

Error: This expression (1.0) has type float but an expression was expected of int

Naively trying to enforce polymorphism doesn't work either:

let print_both: 'a. ('a -> 'a) -> unit = fun f ->
 print_int (f 1);
 print_float (f 1.0)

As a matter of fact, neither will this:

let print1: 'a. ('a -> 'a) -> unit = fun f -> print_int (f 1)

Error: This definition has type (int -> int) -> unit
which is less general than 'a. ('a -> 'a) -> unit

What am I missing? How would you go about writing such a function?

Many thanks,
Guillaume

--
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs