ocaml - Dynamic binding using a ref cell -


i understand can't this, want understand precisely why.

module m : sig    type 'a t   val call : 'a t -> 'a option end = struct    type 'a t   let state : ('a t -> 'a option) ref = ref (fun _ -> none)   let call : ('a t -> 'a option) = fun x -> !state x end 

results in:

error: signature mismatch: modules not match:     sig          type 'a t         val state : ('_a t -> '_a option) ref         val call : '_a t -> '_a option     end not included in     sig          type 'a t          val call : 'a t -> 'a option      end      values not match:         val call : '_a t -> '_a option     not included in         val call : 'a t -> 'a option 

why abstract types not compatible here?

my gut tells me has vs late binding, i'm looking exact description of type system doing here.

one way @ field state can't have polymorphic value ascribe it, because mutable values can't polymorphic. references @ monomorphic (as indicated '_a notation type variable).

if try declare similar reference in toplevel, you'll see same effect:

# let lfr: ('a list -> 'a option) ref = ref (fun x -> none);; val lfr : ('_a list -> '_a option) ref = {contents = <fun>} 

the type variable '_a indicates single type hasn't yet been determined.

the reason references can't polymorphic it's unsound. if allow references generalized (polymorphic) it's easy produce programs go horribly wrong. (in practice means crash , core dump.)

the issue of soundness discussed near beginning of paper: jacques garrigue, relaxing value restriction (which refer periodically when forget how things work).

update

what think want "rank 2 polymorphism". i.e., want field type polymorphic. can in ocaml long declare type. usual method use record type:

# type lfrec = { mutable f: 'a. 'a list -> 'a option };; type lfrec = { mutable f : 'a. 'a list -> 'a option; } # let x = { f = fun x -> none };; val x : lfrec = {f = <fun>} # x.f ;; - : 'a list -> 'a option = <fun> 

the following code compiles me using lfrec instead of reference:

module m : sig   type 'a t   val call : 'a t -> 'a option end = struct   type 'a t   type lfrec = { mutable f: 'a. 'a t -> 'a option }   let state: lfrec = { f = fun _ -> none }   let call : ('a t -> 'a option) = fun x -> state.f x end 

Comments

Popular posts from this blog

How to understand 2 main() functions after using uftrace to profile the C++ program? -

c# - Update a combobox from a presenter (MVP) -

How to put a lock and transaction on table using spring 4 or above using jdbcTemplate and annotations like @Transactional? -