From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id C99587FB4A for ; Fri, 19 Dec 2014 16:33:55 +0100 (CET) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of gabriel.scherer@gmail.com) identity=pra; client-ip=209.85.214.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="gabriel.scherer@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of gabriel.scherer@gmail.com designates 209.85.214.170 as permitted sender) identity=mailfrom; client-ip=209.85.214.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="gabriel.scherer@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-ob0-f170.google.com) identity=helo; client-ip=209.85.214.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="postmaster@mail-ob0-f170.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AikBAApElFTRVdaqm2dsb2JhbABag1hYBIMBs1yPRIVxAoEVBxYBAQEBAREBAQEBAQYLCwkULoQNAQEEEhEEGQEbEgsBAwwGBQsNAgIJHQICIgERAQUBChIGExIQh3UBAxENrgM+MYsugWuCd4svChknAwpUhGsBAQEBAQUBAQEBAQEWAQUOgROOUQeCaIFBBYQrBo0ahTSBDTCMUoFvEiOBDAmEET0xgkMBAQE X-IPAS-Result: AikBAApElFTRVdaqm2dsb2JhbABag1hYBIMBs1yPRIVxAoEVBxYBAQEBAREBAQEBAQYLCwkULoQNAQEEEhEEGQEbEgsBAwwGBQsNAgIJHQICIgERAQUBChIGExIQh3UBAxENrgM+MYsugWuCd4svChknAwpUhGsBAQEBAQUBAQEBAQEWAQUOgROOUQeCaIFBBYQrBo0ahTSBDTCMUoFvEiOBDAmEET0xgkMBAQE X-IronPort-AV: E=Sophos;i="5.07,607,1413237600"; d="scan'208";a="114201844" Received: from mail-ob0-f170.google.com ([209.85.214.170]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 19 Dec 2014 16:33:54 +0100 Received: by mail-ob0-f170.google.com with SMTP id wp18so12917634obc.1; Fri, 19 Dec 2014 07:33:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=r3DLmbSg/hvPfVnKzoO4LVFqgJQWaHBUFyP4qTfxczI=; b=KEXHbRelYu8FBoMUYPH+cNZl0n1dy6GTrc/dzfcpy9LSEp/tBcGMh120JbbXoWPnBw SkQrGCZH6fBkVQLEnB4CxH+8mm9zPBEavIvuDLrqqig/jFIsSEm4LTjC5bslh5S6AcyO W2Xc9vg6uFw1ch8+zCnZjIykC910V6y4DI9tpPUQW++x8Prne4DtMyZZ1MIHPn+3b/4G dr1Cnt1S5Mq91n+1JkYXzkXTeA10fLaVpuUqjgYrXPOGnrxTnOeEDtsELfSvFlIXigxe 8NcuRS8KVCc/SFgVCmbyI4F+IEBiSPsATXSGFBSJoGlOZlt86uYU6ccCkZ3Qn+GVft8M l16g== X-Received: by 10.202.78.139 with SMTP id c133mr4850859oib.93.1419003233914; Fri, 19 Dec 2014 07:33:53 -0800 (PST) MIME-Version: 1.0 Received: by 10.76.5.171 with HTTP; Fri, 19 Dec 2014 07:33:12 -0800 (PST) In-Reply-To: <20141219143039.425107b3@alcazar2> References: <20141219143039.425107b3@alcazar2> From: Gabriel Scherer Date: Fri, 19 Dec 2014 16:33:12 +0100 Message-ID: To: Maxence Guesdon Cc: "caml-list@inria.fr" Content-Type: text/plain; charset=UTF-8 Subject: Re: [Caml-list] Function not polymorphic enough My understanding of the issue is that the type of "extend" cannot be specified without first-class polymorphism (talking about argument types that are polymorphic, instead of prenex polymorphism at the very beginning of the function type). extend should take a function of type ('a . ('a -> unit) -> 'a list) -> unit). To do that in OCaml, you should explicitly take a first-class polymorphic argument (this cannot be inferred), namely a record or object that has a polymorphic field/method. Using the polymorphic record approach, this means you need a definition type t = {poly : 'a . ('a -> unit) -> 'a list -> unit} that is *not* local to your definition, so that users of "extend" can talk about it. (You could use an object type if you want a structural rather than nominal type here.) Using this idea, there is actually no need to define a type locally, a simple reference on my t will do, which gives the following: # let (fn, extend) = let v = ref { poly = fun _f _li -> assert false } in let fn f li = !v.poly f li in let extend g = v := g !v in (fn, extend);; val fn : ('_a -> unit) -> '_a list -> unit = val extend : (t -> t) -> unit = If you want to non-polymorphic variables to go away, you can reveal that "fn" is really a t: # let (fn, extend) = let v = ref { poly = fun _f _li -> assert false } in let fn = { poly = fun f li -> !v.poly f li } in let extend g = v := g !v in (fn, extend);; val fn : t = {poly = } val extend : (t -> t) -> unit = On Fri, Dec 19, 2014 at 2:30 PM, Maxence Guesdon wrote: > Hello, > > With the following code: > > let (fn, extend) = > let module M = struct > type t = { mutable f : 'a. ('a -> unit) -> 'a list -> unit } > let v = > { f = fun (type a) -> fun (poly_a : a -> unit) -> fun _ -> > assert false > } > end in > let fn = fun f x -> M.v.M.f x in > let extend g = M.v.M.f <- g M.v.M.f in > (fn, extend) > > I get the following message about " g M.v.M.f": > Error: This field value has type ('b -> unit) -> 'b list -> unit > which is less general than 'a. ('a -> unit) -> 'a list -> unit > > Does anyone know how to make "g M.v.M.f" general enough ? > > Regards, > > Maxence > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs