"Damien Guichard" <alphabl...@orange.fr> writes: >> I once faced this situation and the solution is to use modules. > That is one good practical solution. > > The simpler solution that immediatly came to my mind is eta-expansion. > > type foo = {bar : 'a. 'a -> 'a} > let a : int -> int = fun x -> x > let baz = {bar = fun x -> (Obj.magic a) x}
This would create a new closure though. Wastes time and space. Bad if you create a million foo's all with the same function. > However it issues a warning so i acknowledge it's less elegant. Which I don't quite understand. > - damien Why not use magic on the overall type of the record instead of the individual function? # type foo = { foo : 'a. 'a -> 'a; } type 'a bar = {bar : 'a -> 'a} let a : int -> int = fun x -> x let baz = (Obj.magic {bar = a} : foo);; type foo = { foo : 'a. 'a -> 'a; } type 'a bar = { bar : 'a -> 'a; } val a : int -> int = <fun> val baz : foo = {foo = <fun>} It means duplicating the record type but you can magic it without warnings. Overall I have to say though that you are doing something wrong here. (Should I assume your actual use case is larger than this simple example?) # let b x = x + 1 let buzz = (Obj.magic {bar = b} : foo) buzz.foo [1;2;3];; val b : int -> int = <fun> val buzz : foo = {foo = <fun>} - : int list = [-2330612807164231680] Doesn't always segfault but lets get nastier: # (buzz.foo buzz).foo 1;; zsh: segmentation fault ocaml The obj.magic only works safely if the function you use is of type 'a -> 'a (even if the interface restricts it to a less general type). The right solution would be to loosen the interface to use the more general type. MfG Goswin _______________________________________________ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs