From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 18F617FC18 for ; Mon, 16 Feb 2015 14:14:34 +0100 (CET) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of info@gerd-stolpmann.de) identity=pra; client-ip=212.227.17.10; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="info@gerd-stolpmann.de"; x-sender="info@gerd-stolpmann.de"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of info@gerd-stolpmann.de) identity=mailfrom; client-ip=212.227.17.10; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="info@gerd-stolpmann.de"; x-sender="info@gerd-stolpmann.de"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mout.kundenserver.de) identity=helo; client-ip=212.227.17.10; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="info@gerd-stolpmann.de"; x-sender="postmaster@mout.kundenserver.de"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0D/AADI7OFUnAoR49RTCYNYWoMDvzAGhXUCgRZDAQEBAQEBEAEBAQEBBg0JCRQuhA0BBAEjBC4kBQsLQgICVwYTCYgcDAm1UpZhAQEBAQEBBAEBAQEBHYsMhAERNSYHgi0MLxGBMQWFWoodAYh3gRiFNAMhiF+DPoQRbgGBCoE4AQEB X-IPAS-Result: A0D/AADI7OFUnAoR49RTCYNYWoMDvzAGhXUCgRZDAQEBAQEBEAEBAQEBBg0JCRQuhA0BBAEjBC4kBQsLQgICVwYTCYgcDAm1UpZhAQEBAQEBBAEBAQEBHYsMhAERNSYHgi0MLxGBMQWFWoodAYh3gRiFNAMhiF+DPoQRbgGBCoE4AQEB X-IronPort-AV: E=Sophos;i="5.09,587,1418079600"; d="asc'?scan'208";a="100219406" Received: from mout.kundenserver.de ([212.227.17.10]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 16 Feb 2015 14:14:33 +0100 Received: from office1.lan.sumadev.de ([88.69.159.115]) by mrelayeu.kundenserver.de (mreue101) with ESMTPSA (Nemesis) id 0LkhLo-1Xp6gW1B9o-00aVpv; Mon, 16 Feb 2015 14:14:32 +0100 Received: from [192.168.65.10] (unknown [192.168.65.10]) by office1.lan.sumadev.de (Postfix) with ESMTPSA id B0596DC05D; Mon, 16 Feb 2015 14:14:31 +0100 (CET) Message-ID: <1424092463.31167.22.camel@e130.lan.sumadev.de> From: Gerd Stolpmann To: Jean Saint-Remy Cc: "caml-list@inria.fr" Date: Mon, 16 Feb 2015 14:14:23 +0100 In-Reply-To: <419599633.6386715.1424045192831.JavaMail.yahoo@mail.yahoo.com> References: <419599633.6386715.1424045192831.JavaMail.yahoo@mail.yahoo.com> Content-Type: multipart/signed; micalg="pgp-sha1"; protocol="application/pgp-signature"; boundary="=-fh2On/C/uGBGr/oHPZqm" X-Mailer: Evolution 3.10.4-0ubuntu2 Mime-Version: 1.0 X-Provags-ID: V03:K0:cB7hCGqH3F3KXoljtOJo9cd2u0+Kxr+5ehjT9jOyi+LjBpKGyjd 3W1lNTA9zWHPiNOkdpTuL4WyMMiFtCtvGinRk0VxjKT0oQD0UlcG/aQ9WZq884EAVvtoIpN m2sxFpFkweNn76OiuxdvDIri7WJ4leMP2Te9K2sTQdbDuQ9kA02FC/kZxyPye5oL5zbivas R4BJSpZZ1Pn7hGkzSDsXw== X-UI-Out-Filterresults: notjunk:1; Subject: Re: [Caml-list] explicit polymorphic types in record fields --=-fh2On/C/uGBGr/oHPZqm Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Am Montag, den 16.02.2015, 00:06 +0000 schrieb Jean Saint-Remy: > Hi, >=20 >=20 > I was reading the ocaml manual section 1.5 where an explicit > polymorphic type can be declared. I wanted to know if the trailing > dot '.' is a special case "marker" only and does not have anything to > do with how we distinguish floating point multiplication, division, > subtraction, and addition, and nothing to do with accessing the > elements of an array. Yes, it is part of a special notation. > Without the trailing dot we cannot declare any such polymorphic > fields no how, no way. I was also surprised to find this was possible. >=20 >=20 >=20 > [The manual says] In some special cases, you may need to store a > polymorphic function in a data structure, keeping its polymorphism. > Without user-provided type annotations, this is not allowed, as > polymorphism is only introduced on a global level.=20 It's not the global level, but the scope of the definition, e.g. compare your idref with: type 'a idref2 =3D { mutable id2 : 'a -> 'a } Here, you need to instantiate 'a per use of idref2 (e.g. int idref2), i.e. 'a is bound somewhere in the environment. This also allows polymorphism if the environment generalizes 'a (e.g. when 'a is made polymorphic in a let binding). The difference becomes more visible when you embed idref/idref2 in other data structures, say a list: type idreflist =3D idref list type 'a idref2list =3D 'a idref2 list As you see, the second form only permits lists where 'a is the same for all elements, whereas in the first form 'a is polymorphic per element. So: # let identity x =3D x;; val identity : 'a -> 'a =3D # let identity2 x =3D prerr_endline "hi"; x;;=20=20=20 val identity2 : 'a -> 'a =3D # let l1 =3D [ { id =3D identity }; { id =3D identity2 } ];; val l1 : idref list =3D [{id =3D }; {id =3D }] # let l2 =3D [ { id2 =3D identity }; { id2 =3D identity2 } ];; val l : '_a idref2 list =3D [{id2 =3D }; {id2 =3D }] # (List.hd l1).id "string";; - : string =3D "string" # (List.hd l1).id 12;;=20=20=20=20=20=20 - : int =3D 12 # (List.hd l2).id2 "string";; - : string =3D "string" # (List.hd l2).id2 34;;=20=20=20=20=20 Error: This expression has type int but an expression was expected of type string # (List.nth l2 1).id2 34;;=20=20 Error: This expression has type int but an expression was expected of type string Beware of this: # [{id =3D String.copy }];; Error: This field value has type string -> string which is less general than 'a. 'a -> 'a # [{id2 =3D String.copy }];; - : string idref2 list =3D [{id2 =3D }] This is why the per-element polymorphism is normally not the right choice: it is not only possible but even required that the function is polymorphic. > However, you can give explicitly polymorphic types to record fields. > # type idref =3D { mutable id: 'a. 'a -> 'a };; > type idref =3D { mutable id : 'a. 'a -> 'a; } >=20 > # let r =3D {id =3D fun x -> x};; > val r : idref =3D {id =3D } >=20 > # let g s =3D (s.id 1, s.id true);; > val g : idref -> int * bool =3D >=20 > # r.id <- (fun x -> print_string "called id\n"; x);; > - : unit =3D () >=20 > # g r;; > called id > called id > - : int * bool =3D (1, true) > I am having difficulty reading the first line, the type declaration > "type idref =3D { mutable id : 'a. 'a -> 'a } ;;" When I look at the > way we are accessing the field values on line 3, it does look like > accessing member fields in other languages and it does superficially > resemble array indexing as in "let str =3D "abcdef" ;; str.[1] ;; -: > char =3D 'b'". The two ways we are using the dot '.' are very distinct. > Is that correct? Yes. The dot in s.id is the normal record member access. It has nothing to do with the dot in the polymorphic type expression. > The second is the common place indexing, whereas the first is just a > "marker". I could not declare the fields for example as a polymorphic > tuple for instance: "type idref =3D { mutable 'a * 'b -> 'a }" nor "type > idref =3D { mutable 'a. 'b -> 'a }". type idref =3D { mutable 'a 'b . 'b -> 'a } > The latter is just nonsense, the 'b is undefined. But we could have a > two field record by just repeating the type definitions. "let idref =3D > { mutable 'a. 'a -> 'a; mutable 'b. 'b -> 'b }". The polymorphic type > does not have any restriction, it appears we could have any > fundamental type we wanted. The type 'a variable must be repeated, it > is not enough to say "type idref =3D { mutable 'a. -> 'a };;" Is it > correct then to read the declaration in this way: the type 'a > polymorphic type as a polymorphic variable of type 'a. I know it > sounds redundant, but that is how I am reading the syntax. Yes. This notation actually picks up the notation for logical quantification in mathematics (e.g. =E2=88=80 x =E2=88=8A S . p(x) ). On th= e left side of the dot the variables are introduced which are used on the right side. Gerd >=20 >=20 > Thank you for clarifying this for me. >=20 >=20 > jean >=20 --=20 ------------------------------------------------------------ Gerd Stolpmann, Darmstadt, Germany gerd@gerd-stolpmann.de My OCaml site: http://www.camlcity.org Contact details: http://www.camlcity.org/contact.html Company homepage: http://www.gerd-stolpmann.de ------------------------------------------------------------ --=-fh2On/C/uGBGr/oHPZqm Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJU4e0vAAoJEAaM4b9ZLB5T+LoH/RyXiG7qpv2sQ3LrgnZtIr3U No0IQy9pkKT24lVKtwivQLKKOlwCk2DupjadhTyHinyfs/OWhu7D/oyFQzfmyRIC TL9+j7SpKheHZUBrEnAejZzLRkCZ7vgiA6Ws3TfEI4ILg+wpBQUn5ZST6ojOCqcJ 4xduIN6Sw9FUgKZfK669G+ILPfjFv5eI7OCPmXVc4biyc/peSadSHNTcgOewy9Wx ZVpCdRFKPiIZM+ZzAPvwQMHKYmHJoN6oR1ME96za5wj/3Ra7V0+ZEMgGbvJxUiFz uzd9Z20IgDNPwjjyNZwY2vp6nVlmGGc8rFfX14UWjdbBx9QTY6JB+y7GnRUi2ug= =nuME -----END PGP SIGNATURE----- --=-fh2On/C/uGBGr/oHPZqm--