Version française
Home     About     Download     Resources     Contact us    
Browse thread
Polymorphism question...
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: David Allsopp <dra-news@m...>
Subject: Polymorphism question...
If I write:

let n = ref 0
in
  fun x -> incr n; x

then I get a function with type '_a -> '_a --- i.e. with a non-instantiated
type variable rather than the slightly curious polymorphic identity function
that I was expecting.

If I write:

let n = ref 0
fun x -> incr n; x

then I get a polymorphic function with type 'a -> 'a which was what I was
after.

My question: why does declaring the int ref n locally prevent the type of
the function being generalised when if I just put n at "global" scope it
would be? I'm sure there's a reason relating to the standard problem of refs
and inferred polymorphic type variables, but I'm curious as to what is
different in the type system between the two ways of expressing this.

Furthermore, in SML, the code:

local
  val n = ref 0
in
  fun f x = (n := !n + 1; x)
end;

correctly produces f : 'a -> 'a

So what's different in O'Caml?


David


PS I hit this by mistake when sharing state variables between two related
functions in a module. Rather than declaring:

let some_global = ref whatever

let function1 = (* something that uses some_global *)

let function2 = (* something else that uses some_global *)

let function3 = (* something different that doesn't use some_global *)

I prefer to say:

let (function1, function2) =
  let some_global = ref whatever
  in
    let function1 = ...
    and function2 = ...
    in
      (function1, function2)

let function3 = ...

and accept the unnecessary boxing/unboxing at program launch for a bit of
program neatness (i.e. the "global" is only available to the functions that
need it). SML has a neater construct for this where you can say

local
  val some_global = ref whatever
in
  fun function1 = ...
  and function2 = ...
end;

which is something I rather miss in O'Caml!