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 A3CC37FE44 for ; Wed, 6 Jul 2016 15:35:45 +0200 (CEST) IronPort-PHdr: 9a23:0MosbhwuZu8MDTXXCy+O+j09IxM/srCxBDY+r6Qd0eIRIJqq85mqBkHD//Il1AaPBtSDragawLSO+4nbGkU4qa6bt34DdJEeHzQksu4x2zIaPcieFEfgJ+TrZSFpVO5LVVti4m3peRMNQJW2WVTerzWI4CIIHV2nbEwud7yzQNCZ0Zz//tvx0qWbWx9Piju5bOE6BzSNhiKViPMrh5B/IL060BrDrygAUe1XwWR1OQDbxE6ktY+YtaRu+CVIuv8n69UIEeCjJ/x5HvRkC2EDMmM17czv/TzKSweV93gdVC1ClxNODxLU7xD8dpbqqjHzraxnxX/JE9fxSOUWXj+v67ZtfyRpkiAbf2ob92rajt12yplWuhW9jwF5wpCRapmeMPdke6TbYZUUXzwSDY5qSyVdD9bkPMM0BO0bMLMd9tGlqg== Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=Jocelyn.Serot@univ-bpclermont.fr; spf=None smtp.mailfrom=Jocelyn.Serot@univ-bpclermont.fr; spf=None smtp.helo=postmaster@mta02.udamail.fr Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of Jocelyn.Serot@univ-bpclermont.fr) identity=pra; client-ip=193.49.117.21; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="Jocelyn.Serot@univ-bpclermont.fr"; x-sender="Jocelyn.Serot@univ-bpclermont.fr"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of Jocelyn.Serot@univ-bpclermont.fr) identity=mailfrom; client-ip=193.49.117.21; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="Jocelyn.Serot@univ-bpclermont.fr"; x-sender="Jocelyn.Serot@univ-bpclermont.fr"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mta02.udamail.fr) identity=helo; client-ip=193.49.117.21; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="Jocelyn.Serot@univ-bpclermont.fr"; x-sender="postmaster@mta02.udamail.fr"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0APAgA/CH1XhxV1McFdhAcNfLQlhn0ihXYCgSk8EAEBAQEBAQEBEQEBAQoLCQkhL4IyghoBAQQBIwRSBQsJAhgqAgICVQYTiCgMAQmPAp0dj3YBAQEBAQEBAQEBAQEBAQEBAQEBAQEODogfCIJNhFeCaiuCLwEEjgSLD4MvglqBMYlFhxOFX4gZh28CNYInEQuBTmwBiHEBAQE X-IPAS-Result: A0APAgA/CH1XhxV1McFdhAcNfLQlhn0ihXYCgSk8EAEBAQEBAQEBEQEBAQoLCQkhL4IyghoBAQQBIwRSBQsJAhgqAgICVQYTiCgMAQmPAp0dj3YBAQEBAQEBAQEBAQEBAQEBAQEBAQEODogfCIJNhFeCaiuCLwEEjgSLD4MvglqBMYlFhxOFX4gZh28CNYInEQuBTmwBiHEBAQE X-IronPort-AV: E=Sophos;i="5.28,319,1464645600"; d="ml'63?mli'63?gz'63,50?tar'63,50,49?scan'63,50,49,208,49,50,63";a="225807141" Received: from mta02.udamail.fr ([193.49.117.21]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Jul 2016 15:35:44 +0200 Received: from mta02.udamail.fr (localhost.localdomain [127.0.0.1]) by mta02.udamail.fr (Postfix) with ESMTPS id CD942160167; Wed, 6 Jul 2016 15:35:43 +0200 (CEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by mta02.udamail.fr (Postfix) with ESMTP id BDFBA1601D9; Wed, 6 Jul 2016 15:35:43 +0200 (CEST) X-Virus-Scanned: amavisd-new at mta02.udamail.fr Received: from mta02.udamail.fr ([127.0.0.1]) by localhost (mta02.udamail.fr [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id Ri8fxmbmr9kk; Wed, 6 Jul 2016 15:35:43 +0200 (CEST) Received: from proxy01.udamail.fr (proxy01.udamail.fr [193.49.117.18]) by mta02.udamail.fr (Postfix) with ESMTPS id 97FE3160167; Wed, 6 Jul 2016 15:35:43 +0200 (CEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by proxy01.udamail.fr (Postfix) with ESMTP id 92B7615E04C; Wed, 6 Jul 2016 15:35:43 +0200 (CEST) Received: from proxy01.udamail.fr ([127.0.0.1]) by localhost (proxy01.udamail.fr [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 9IjjoYtOIIBW; Wed, 6 Jul 2016 15:35:42 +0200 (CEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by proxy01.udamail.fr (Postfix) with ESMTP id 266FD15E04D; Wed, 6 Jul 2016 15:35:42 +0200 (CEST) X-Virus-Scanned: amavisd-new at proxy01.udamail.fr Received: from proxy01.udamail.fr ([127.0.0.1]) by localhost (proxy01.udamail.fr [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id Ax61Xh_9D9Nt; Wed, 6 Jul 2016 15:35:41 +0200 (CEST) Received: from [192.168.0.42] (lav63-2-88-164-92-250.fbx.proxad.net [88.164.92.250]) by proxy01.udamail.fr (Postfix) with ESMTPSA id 3682F15E04C; Wed, 6 Jul 2016 15:35:41 +0200 (CEST) Content-Type: multipart/mixed; boundary="Apple-Mail=_4ADC4EB1-F664-4D96-B59C-50D5EB8031A5" Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.6\)) From: =?iso-8859-1?Q?Jocelyn_S=E9rot?= In-Reply-To: <44481375.r3GYhIioXc@molnar> Date: Wed, 6 Jul 2016 15:35:39 +0200 Cc: OCaml Mailing List , Gerd Stolpmann Message-Id: <6E56056A-0730-4CE3-AEAD-636927B6DA20@univ-bpclermont.fr> References: <64440D5D-1FC8-4C53-9520-D9D3D21F8FE5@univ-bpclermont.fr> <44623127-96C5-43FB-828D-0F42DCCBA36B@univ-bpclermont.fr> <1467798868.25014.8.camel@e130.lan.sumadev.de> <44481375.r3GYhIioXc@molnar> To: Mikhail Mandrykin X-Mailer: Apple Mail (2.1878.6) Subject: Re: [Caml-list] Q: functors and "has a" inheritance --Apple-Mail=_4ADC4EB1-F664-4D96-B59C-50D5EB8031A5 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=windows-1252 Hi Mikhail, This solves the problem !=20 For those interested, i attach the final code. Note that I didn=92t even need your last patch.=20 Thanks A LOT Jocelyn --Apple-Mail=_4ADC4EB1-F664-4D96-B59C-50D5EB8031A5 Content-Disposition: attachment; filename=myset2.tar.gz Content-Type: application/x-gzip; x-unix-mode=0644; name="myset2.tar.gz" Content-Transfer-Encoding: base64 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 --Apple-Mail=_4ADC4EB1-F664-4D96-B59C-50D5EB8031A5 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Le 6 juil. 2016 =C3=A0 14:59, Mikhail Mandrykin a =C3= =A9crit : > Hello, >=20 > On =D1=81=D1=80=D0=B5=D0=B4=D0=B0, 6 =D0=B8=D1=8E=D0=BB=D1=8F 2016 =D0=B3= . 11:54:28 MSK Gerd Stolpmann wrote: >> Am Mittwoch, den 06.07.2016, 10:44 +0200 schrieb Jocelyn S=C3=A9rot: >>> Hi Nicolas, >=20 >> Your design might work when you change Product: >>=20 >> module Product (S1: T) (S2: T) >> (P : T with type elt =3D S1.elt * S2.elt >> and type attr =3D S1.attr * S2.attr) >> sig >> val product: S1.t -> S2.t -> P.t >> end >>=20 >> i.e. the "real" product module is the argument P, and this functor only >> defines the product function. This way you can instantiate it for any P. >=20 > It's also possible to explicitly name the anonymous module "struct type t= =3D=20 > S1.elt * S2.elt let compare =3D compare end" e.g. by exposing it in the o= utput=20 > signature of Product: > module E : Set.OrderedType with type t =3D S1.elt * S2.elt > include T with type elt =3D E.t and type t =3D Make(E).t > instead of=20 > include T with type elt =3D S1.elt * S2.elt > in myset.mli (module Product) >=20 > Then if Product implementation is changed appropriately i.e. > module E =3D (struct > type t =3D S1.elt * S2.elt > let compare =3D compare > end) > module R =3D Make (E) >=20 > instead of > module R =3D > Make > (struct > type t =3D S1.elt * S2.elt > let compare =3D compare > end) > include R > in myset.ml (module Product), >=20 > the anonymous module can be named and shared explicitly: > module P =3D Myset.Product(S1.S)(S2.S) > module R =3D > Make > (P.E) > (struct type t =3D S1.attr * S2.attr let compare =3D compare end) > include R > instead of > module R =3D > Make > (struct type t =3D S1.elt * S2.elt let compare =3D compare end) > (struct type t =3D S1.attr * S2.attr let compare =3D compare end) > include R > module P =3D Myset.Product(S1.S)(S2.S) > in myset.ml (module Product) >=20 > The only remaining problem then is missing equality between elt and S.elt= in=20 > the signature Myseta.T: > module S: Myset.T --> module S: Myset.T with type elt =3D elt > This makes it work with elems =3D P.product ... > Then the additional constraint > ... > and type S.t =3D Myset.Product(S1.S)(S2.S).t > in myset.mli > can be turned into > module P : sig module E : Set.OrderedType end > ... and type S.t =3D Myset.Make(P.E).t >=20 > Regards, Mikhail >>=20 >> Gerd >>=20 >>> I guess it is because re-use the [Myseta.Product] functor only views >>> the abstract types exposed by the [Myset.Make] and [Myset.Product] >>> output signatures. >>>=20 >>>=20 >>> Seems therefore i am really stuck :( >>>=20 >>>=20 >>> Jocelyn >>>=20 >>>=20 >>> Le 6 juil. 2016 =C3=A0 09:49, Nicolas Ojeda Bar >>>=20 >>> a =C3=A9crit : >>>> Hi Jocelyn >>>>=20 >>>>=20 >>>> One issue is that you have two modules, P and R.S, of the form >>>> Set.Make(X), Set.Make (X') for modules X and X' which are >>>> structurally equal. Unfortunately this is not enough for the OCaml >>>> module system to deduce that P.t and R.S.t are compatible. In >>>> general if F is a functor with output signature S and t is abstract >>>> type in S, then F(X).t and F(X').t will be compatible exactly when X >>>> and X' are literally the same module. I don't think you will be >>>> able to fix this by adding type sharing constrains. >>>>=20 >>>>=20 >>>> Cheers >>>> Nicolas >>>>=20 >>>>=20 >>>>=20 >>>> On Tue, Jul 5, 2016 at 5:25 PM, Jocelyn S=C3=A9rot >>>>=20 >>>> wrote: >>>> Dear all, >>>>=20 >>>>=20 >>>> I=E2=80=99m stuck with a problem related with the use of functo= rs >>>> for implementing a library. >>>> The library concerns Labeled Transition Systems but i=E2=80=99ll >>>> present it in a simplified version using sets. >>>>=20 >>>>=20 >>>> Suppose i have a (very simplified !) Set module, which i >>>> will call Myset to distinguish from that of the standard >>>> library : >>>>=20 >>>>=20 >>>> =E2=80=94=E2=80=94=E2=80=94=E2=80=94 myset.mli >>>> module type T =3D sig >>>>=20 >>>> type elt >>>> type t >>>> val empty: t >>>> val add: elt -> t -> t >>>> val elems: t -> elt list >>>> val fold: (elt -> 'a -> 'a) -> t -> 'a -> 'a >>>>=20 >>>> end >>>>=20 >>>>=20 >>>> module Make (E : Set.OrderedType) : T with type elt =3D E.t >>>> =E2=80=94=E2=80=94=E2=80=94 >>>>=20 >>>>=20 >>>> =E2=80=94=E2=80=94=E2=80=94=E2=80=94 myset.ml >>>> module type T =3D sig =E2=80=A6 (* idem myset.mli *) end >>>>=20 >>>>=20 >>>> module Make (E : Set.OrderedType) =3D struct >>>>=20 >>>> module Elt =3D E >>>> type elt =3D E.t >>>> type t =3D { elems: elt list; } >>>> let empty =3D { elems =3D [] } >>>> let add q s =3D { elems =3D q :: s.elems } (* obviously >>>>=20 >>>> wrong, but does not matter here ! *) >>>>=20 >>>> let elems s =3D s.elems >>>> let fold f s z =3D List.fold_left (fun z e -> f e z) z >>>>=20 >>>> s.elems >>>> end >>>> =E2=80=94=E2=80=94=E2=80=94 >>>>=20 >>>>=20 >>>> First, i add a functor for computing the product of two >>>> sets : >>>>=20 >>>>=20 >>>> =E2=80=94=E2=80=94=E2=80=94=E2=80=94 myset.mli (cont=E2=80=99d) >>>> module Product (S1: T) (S2: T) : >>>> sig >>>>=20 >>>> include T with type elt =3D S1.elt * S2.elt >>>> val product: S1.t -> S2.t -> t >>>>=20 >>>> end >>>> =E2=80=94=E2=80=94=E2=80=94 >>>>=20 >>>>=20 >>>> =E2=80=94=E2=80=94=E2=80=94=E2=80=94 myset.ml (cont=E2=80=99d) >>>> module Product >>>>=20 >>>> (S1: T) >>>> (S2: T) =3D >>>>=20 >>>> struct >>>>=20 >>>> module R =3D >>>>=20 >>>> Make (struct type t =3D S1.elt * S2.elt let compare =3D >>>>=20 >>>> compare end) >>>>=20 >>>> include R >>>> let product s1 s2 =3D >>>>=20 >>>> S1.fold >>>>=20 >>>> (fun q1 z -> >>>>=20 >>>> S2.fold >>>>=20 >>>> (fun q2 z -> R.add (q1,q2) z) >>>> s2 >>>> z) >>>>=20 >>>> s1 >>>> R.empty >>>>=20 >>>> end >>>> =E2=80=94=E2=80=94=E2=80=94 >>>>=20 >>>>=20 >>>> Here=E2=80=99s a typical usage of the Myset module : >>>>=20 >>>>=20 >>>> =E2=80=94=E2=80=94 ex1.ml >>>> module IntSet =3D Myset.Make (struct type t =3D int let compare >>>> =3D compare end) >>>> module StringSet =3D Myset.Make (struct type t =3D string let >>>> compare =3D compare end) >>>>=20 >>>>=20 >>>> let s1 =3D IntSet.add 1 (IntSet.add 2 IntSet.empty) >>>> let s2 =3D StringSet.add "a" (StringSet.add "b" >>>> StringSet.empty) >>>>=20 >>>>=20 >>>> module IntStringSet =3D Myset.Product (IntSet) (StringSet) >>>>=20 >>>>=20 >>>> let s3 =3D IntStringSet.product s1 s2 >>>> =E2=80=94=E2=80=94 >>>>=20 >>>>=20 >>>> So far, so good. >>>>=20 >>>>=20 >>>> Now suppose i want to =C2=AB augment =C2=BB the Myset module so= that >>>> some kind of attribute is attached to each set element. I >>>> could of course just modify the definition of type [t] and >>>> the related functions in the files [myset.ml] and >>>> [myset.mli]. But suppose i want to reuse as much as possible >>>> the code already written. My idea is define a new module - >>>> let=E2=80=99s call it [myseta] (=C2=AB a =C2=BB for attributes)= - in which the >>>> type [t] will include a type [Myset.t] and the definitions >>>> of this module will make use, as much as possible, of those >>>> defined in [Myset]. >>>>=20 >>>>=20 >>>> Here=E2=80=99s a first proposal (excluding the Product functor = for >>>> the moment) : >>>>=20 >>>>=20 >>>> =E2=80=94=E2=80=94=E2=80=94=E2=80=94 myseta.mli >>>> module type Attr =3D sig type t end >>>>=20 >>>>=20 >>>> module type T =3D sig >>>>=20 >>>> type elt >>>> type attr >>>> type t >>>> module S: Myset.T >>>> val empty: t >>>> val add: elt * attr -> t -> t >>>> val elems: t -> elt list >>>> val attrs: t -> (elt * attr) list >>>> val set_of: t -> S.t >>>> val fold: (elt * attr -> 'a -> 'a) -> t -> 'a -> 'a >>>>=20 >>>> end >>>>=20 >>>>=20 >>>> module Make (E : Set.OrderedType) (A: Attr) : T with type >>>> elt =3D E.t and type attr =3D A.t >>>> =E2=80=94=E2=80=94=E2=80=94 >>>>=20 >>>>=20 >>>> =E2=80=94=E2=80=94=E2=80=94=E2=80=94 myseta.ml >>>> module type Attr =3D sig type t end >>>>=20 >>>>=20 >>>> module type T =3D sig (* idem myseta.mli *) end >>>>=20 >>>>=20 >>>> module Make (E : Set.OrderedType) (A : Attr) =3D struct >>>>=20 >>>> module Elt =3D E >>>> type elt =3D E.t >>>> type attr =3D A.t >>>> module S =3D Myset.Make(E) >>>> type t =3D { elems: S.t; attrs: (elt * attr) list } >>>> let empty =3D { elems =3D S.empty; attrs =3D [] } >>>> let add (e,a) s =3D { elems =3D S.add e s.elems; attrs =3D >>>>=20 >>>> (e,a) :: s.attrs } >>>>=20 >>>> let elems s =3D S.elems s.elems >>>> let attrs s =3D s.attrs >>>> let set_of s =3D s.elems >>>> let fold f s z =3D List.fold_left (fun z e -> f e z) z >>>>=20 >>>> s.attrs >>>> end >>>> =E2=80=94=E2=80=94=E2=80=94 >>>>=20 >>>>=20 >>>> In practice, of course the [Attr] signature will include >>>> other specifications. >>>> In a sense, this is a =C2=AB has a =C2=BB inheritance : wheneve= r i >>>> build a [Myseta] module, i actually build a [Myset] >>>> sub-module and this module is used to implement all the >>>> set-related operations. >>>> Again, so far, so good. >>>> The problem shows when i try to define the [Product] functor >>>> for the [Myseta] module : >>>> It=E2=80=99s signature is similar to that of the [Myset.Product] >>>> functor, with an added sharing constraint for attributes (in >>>> fact, we could imagine a more sophisticated scheme for >>>> merging attributes but cartesian product is here) : >>>>=20 >>>>=20 >>>> =E2=80=94=E2=80=94=E2=80=94=E2=80=94 myset.mli (cont=E2=80=99d) >>>> module Product (S1: T) (S2: T) : >>>> sig >>>>=20 >>>> include T with type elt =3D S1.elt * S2.elt >>>>=20 >>>> and type attr =3D S1.attr * S2.attr >>>>=20 >>>> val product: S1.t -> S2.t -> t >>>>=20 >>>> end >>>> =E2=80=94=E2=80=94=E2=80=94 >>>>=20 >>>>=20 >>>> Now, here=E2=80=99s my current implementation >>>>=20 >>>>=20 >>>> =E2=80=94=E2=80=94=E2=80=94=E2=80=94 myset.ml (cont=E2=80=99d) >>>> module Product >>>>=20 >>>> (S1: T) >>>> (S2: T) =3D >>>>=20 >>>> struct >>>>=20 >>>> module R =3D >>>>=20 >>>> Make >>>>=20 >>>> (struct type t =3D S1.elt * S2.elt let compare =3D compare >>>>=20 >>>> end) >>>>=20 >>>> (struct type t =3D S1.attr * S2.attr let compare =3D >>>>=20 >>>> compare end) >>>>=20 >>>> include R >>>> module P =3D Myset.Product(S1.S)(S2.S) >>>> let product s1 s2 =3D >>>>=20 >>>> { elems =3D P.product (S1.set_of s1) (S2.set_of s2); >>>>=20 >>>> attrs =3D >>>>=20 >>>> List.fold_left >>>>=20 >>>> (fun acc (e1,a1) -> >>>>=20 >>>> List.fold_left (fun acc (e2,a2) -> >>>>=20 >>>> ((e1,e2),(a1,a2))::acc) acc (S2.attrs s2)) >>>>=20 >>>> [] >>>> (S1.attrs s1) } >>>>=20 >>>> end >>>> =E2=80=94=E2=80=94=E2=80=94 >>>>=20 >>>>=20 >>>> I use the [Myseta.Make] functor for building the resulting >>>> module [named R here]. For defining the [product] function, >>>> i first use the [Myset.Product] functor applied on the two >>>> related sub-modules [S1] and [S2] to build the product >>>> module (named P here) and re-use the [product] function of >>>> this module to compute the [elems] component of the result. >>>> The other component is computed directly. >>>> The problem is that when i try to compile this i get this >>>> message : >>>>=20 >>>>=20 >>>> File "myseta.ml", line 44, characters 14-53: >>>> Error: This expression has type P.t =3D >>>> Myset.Product(S1.S)(S2.S).t >>>>=20 >>>> but an expression was expected of type S.t =3D R.S.t >>>>=20 >>>> My intuition is that a sharing constraint is missing >>>> somewhere but i just cannot figure out where to add it. >>>> I tried to rewrite the signature of the [Myseta.Product] >>>> functor (in [myseta.mli]) as : >>>>=20 >>>>=20 >>>> module Product (S1: T) (S2: T) : >>>> sig >>>>=20 >>>> include T with type elt =3D S1.elt * S2.elt >>>>=20 >>>> and type attr =3D S1.attr * S2.attr >>>> and type S.t =3D Myset.Product(S1.S)(S2.S).t (* >>>>=20 >>>> added constraint *) >>>>=20 >>>> val product: S1.t -> S2.t -> t >>>>=20 >>>> end >>>>=20 >>>>=20 >>>> but it did not change anything.. >>>>=20 >>>>=20 >>>> So my question is : is my diagnostic correct and, if yes, >>>> which constraint(s) are missing and where; or, conversely, >>>> am i completely =C2=AB misusing =C2=BB the functor mechanisms f= or >>>> implementing this kind of =C2=AB reuse by inclusion =C2=BB ? >>>>=20 >>>>=20 >>>> Any help will be grealy appreciated : i=E2=80=99ve been reading= and >>>> re-reading about functors for the last two days but have the >>>> impression that at this step, things get more and more >>>> opaque.. :-S >>>>=20 >>>>=20 >>>> In anycase, the source code is >>>> here : http://filez.univ-bpclermont.fr/lamuemlqpm >>>>=20 >>>>=20 >>>> Jocelyn >=20 >=20 > --=20 > Mikhail Mandrykin > Linux Verification Center, ISPRAS > web: http://linuxtesting.org > e-mail: mandrykin@ispras.ru --Apple-Mail=_4ADC4EB1-F664-4D96-B59C-50D5EB8031A5--