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
Post a Comment