let remember =
let cache = ref None in
(fun x -> match !cache with
| Some y -> y
| None -> cache := Some x; x)
;;
Here cache
is closed over by the returned function. But at the point where we declare cache
, we have no information on what the type will be; it'll be determined by whatever the type of x
is and cache
is created when remember
is defined.
But since this is a closure we can do something like this:
> remember 1
1
Now it's clear that cache : int option ref
since we've actually stored something in it. Since there's only ever one cache
, remember
can only ever store one type.
In the next one, you close over 2 things, x
and cache
. Since we create a new cache
ref with each invocation of remember
the type can be fully polymorphic again. The reason the type isn't weakly polymorphic is because we know that we're going to store x
in it and we have x
s type at the time when cache
is created.