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 mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 926297FE44 for ; Wed, 6 Jul 2016 10:44:27 +0200 (CEST) IronPort-PHdr: 9a23:zkwTVRKr4WcFd3uOH9mcpTZWNBhigK39O0sv0rFitYgUIv3xwZ3uMQTl6Ol3ixeRBMOAuqoC0bSempujcFRI2YyGvnEGfc4EfD4+ouJSoTYdBtWYA1bwNv/gYn9yNs1DUFh44yPzahANS47AblHf6ke/8SQVUk2mc1EkfqKvRMb7tIee76iK4ZrdYgFF1nKWQIhZC1GIlzjXrdQcmoB4K6w8mVPjq3pMfPlKlyszfQrA1z613Mq7/YZi/iJMoLphspcYCeSpN5g/GJtzBTEie0U85cnqsxaLaQqU+jNIWWwTll9MAhPZxBD8RJb49CXg4LlTwi6faO/xRr0wSDKV1CZxTwOg3AUAPDM94WeRscFqi75zvRSguVl124XQbZuQM/xiOK3HK4BJDVFdV9pcAnQSSri3aJECWq9YZb5V Authentication-Results: mail3-smtp-sop.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 (mail3-smtp-sop.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=mail3-smtp-sop.national.inria.fr; envelope-from="Jocelyn.Serot@univ-bpclermont.fr"; x-sender="Jocelyn.Serot@univ-bpclermont.fr"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.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=mail3-smtp-sop.national.inria.fr; envelope-from="Jocelyn.Serot@univ-bpclermont.fr"; x-sender="Jocelyn.Serot@univ-bpclermont.fr"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mta02.udamail.fr) identity=helo; client-ip=193.49.117.21; receiver=mail3-smtp-sop.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: A0AGAgB7w3xXhxV1McFdgnCBFw18tEKGfSKFdgKBKzwQAQEBAQEBAQERAQEBCgsJCSEvgjKCGgEBBAEnVwsJAhggAQ1XBhOIKAwBCY4+rRgBAQgBAQEBAQEBAR+IHwiCTYdsgi8BBJNZhTqGCYExiUWHE4VfiBmHbwIPJoInEQuBTmwBiHEBAQE X-IPAS-Result: A0AGAgB7w3xXhxV1McFdgnCBFw18tEKGfSKFdgKBKzwQAQEBAQEBAQERAQEBCgsJCSEvgjKCGgEBBAEnVwsJAhggAQ1XBhOIKAwBCY4+rRgBAQgBAQEBAQEBAR+IHwiCTYdsgi8BBJNZhTqGCYExiUWHE4VfiBmHbwIPJoInEQuBTmwBiHEBAQE X-IronPort-AV: E=Sophos;i="5.28,318,1464645600"; d="scan'208,217";a="184018334" Received: from mta02.udamail.fr ([193.49.117.21]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Jul 2016 10:44:25 +0200 Received: from mta02.udamail.fr (localhost.localdomain [127.0.0.1]) by mta02.udamail.fr (Postfix) with ESMTPS id 8ADDF16010A for ; Wed, 6 Jul 2016 10:44:25 +0200 (CEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by mta02.udamail.fr (Postfix) with ESMTP id 7D5D8160167 for ; Wed, 6 Jul 2016 10:44:25 +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 T3pokPFfuk2f for ; Wed, 6 Jul 2016 10:44:25 +0200 (CEST) Received: from proxy02.udamail.fr (proxy02.udamail.fr [193.49.117.19]) by mta02.udamail.fr (Postfix) with ESMTPS id 658B616010A for ; Wed, 6 Jul 2016 10:44:25 +0200 (CEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by proxy02.udamail.fr (Postfix) with ESMTP id 623FC1622F2 for ; Wed, 6 Jul 2016 10:44:25 +0200 (CEST) Received: from proxy02.udamail.fr ([127.0.0.1]) by localhost (proxy02.udamail.fr [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id ahYkNeT8GlOO for ; Wed, 6 Jul 2016 10:44:24 +0200 (CEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by proxy02.udamail.fr (Postfix) with ESMTP id 861751622F4 for ; Wed, 6 Jul 2016 10:44:24 +0200 (CEST) X-Virus-Scanned: amavisd-new at proxy02.udamail.fr Received: from proxy02.udamail.fr ([127.0.0.1]) by localhost (proxy02.udamail.fr [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 0mRJxeoKzuCc for ; Wed, 6 Jul 2016 10:44:24 +0200 (CEST) Received: from [192.168.0.42] (lav63-2-88-164-92-250.fbx.proxad.net [88.164.92.250]) by proxy02.udamail.fr (Postfix) with ESMTPSA id F3EBF1622F2 for ; Wed, 6 Jul 2016 10:44:23 +0200 (CEST) From: =?iso-8859-1?Q?Jocelyn_S=E9rot?= Content-Type: multipart/alternative; boundary="Apple-Mail=_20C93892-9F28-4EF4-984E-EF6B1D3663E6" Message-Id: <44623127-96C5-43FB-828D-0F42DCCBA36B@univ-bpclermont.fr> Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.6\)) Date: Wed, 6 Jul 2016 10:44:25 +0200 References: <64440D5D-1FC8-4C53-9520-D9D3D21F8FE5@univ-bpclermont.fr> To: OCaml Mailing List In-Reply-To: X-Mailer: Apple Mail (2.1878.6) Subject: Re: [Caml-list] Q: functors and "has a" inheritance --Apple-Mail=_20C93892-9F28-4EF4-984E-EF6B1D3663E6 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=windows-1252 Hi Nicolas, Thanks fro your answer. If i understand correctly, you mean that if i write, say : module type S =3D sig type t val zero: t end module type T =3D sig type t val zero: t end module Make (X : S) =3D (struct type t =3D X.t * X.t let zero =3D X.zero, X= .zero end : T) module M1 =3D Make (struct type t =3D int let zero =3D 0 end) module M2 =3D Make (struct type t =3D int let zero =3D 0 end) then the compiler will never be able to deduce that M1.t and M2.t are indee= d compatible. Am i right ? I guess it is because re-use the [Myseta.Product] functor only views the ab= stract types exposed by the [Myset.Make] and [Myset.Product] output signatu= res. Seems therefore i am really stuck :( Jocelyn Le 6 juil. 2016 =E0 09:49, Nicolas Ojeda Bar = a =E9crit : > Hi Jocelyn >=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. Unfort= unately this is not enough for the OCaml module system to deduce that P.t a= nd R.S.t are compatible. In general if F is a functor with output signatur= e 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 wi= ll be able to fix this by adding type sharing constrains. >=20 > Cheers > Nicolas >=20 >=20 > On Tue, Jul 5, 2016 at 5:25 PM, Jocelyn S=E9rot wrote: > Dear all,=20 >=20 > I=92m stuck with a problem related with the use of functors for implement= ing a library. > The library concerns Labeled Transition Systems but i=92ll present it in = a simplified version using sets. >=20 > Suppose i have a (very simplified !) Set module, which i will call Myset = to distinguish from that of the standard library : >=20 > =97=97=97=97 myset.mli > module type T =3D sig > type elt=20 > type t=20 > val empty: t > val add: elt -> t -> t > val elems: t -> elt list > val fold: (elt -> 'a -> 'a) -> t -> 'a -> 'a > end >=20 > module Make (E : Set.OrderedType) : T with type elt =3D E.t > =97=97=97=20 >=20 > =97=97=97=97 myset.ml > module type T =3D sig =85 (* idem myset.mli *) end >=20 > module Make (E : Set.OrderedType) =3D struct > module Elt =3D E > type elt =3D E.t > type t =3D { elems: elt list; }=20=20 > let empty =3D { elems =3D [] } > let add q s =3D { elems =3D q :: s.elems } (* obviously wrong, but doe= s not matter here ! *) > let elems s =3D s.elems > let fold f s z =3D List.fold_left (fun z e -> f e z) z s.elems > end > =97=97=97=20 >=20 > First, i add a functor for computing the product of two sets : >=20 > =97=97=97=97 myset.mli (cont=92d) > module Product (S1: T) (S2: T) : > sig > include T with type elt =3D S1.elt * S2.elt > val product: S1.t -> S2.t -> t > end > =97=97=97=20 >=20 > =97=97=97=97 myset.ml (cont=92d) > module Product > (S1: T) > (S2: T) =3D > struct > module R =3D > Make (struct type t =3D S1.elt * S2.elt let compare =3D compare end) > include R > let product s1 s2 =3D > S1.fold > (fun q1 z -> > S2.fold > (fun q2 z -> R.add (q1,q2) z) > s2 > z) > s1 > R.empty > end > =97=97=97=20 >=20 > Here=92s a typical usage of the Myset module :=20 >=20 > =97=97 ex1.ml=20 > module IntSet =3D Myset.Make (struct type t =3D int let compare =3D compa= re end) > module StringSet =3D Myset.Make (struct type t =3D string let compare =3D= compare end) >=20 > let s1 =3D IntSet.add 1 (IntSet.add 2 IntSet.empty) > let s2 =3D StringSet.add "a" (StringSet.add "b" StringSet.empty) >=20 > module IntStringSet =3D Myset.Product (IntSet) (StringSet) >=20 > let s3 =3D IntStringSet.product s1 s2 > =97=97 >=20 > So far, so good.=20 >=20 > Now suppose i want to =AB augment =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.m= l] and [myset.mli]. But suppose i want to reuse as much as possible the cod= e already written. My idea is define a new module - let=92s call it [myseta= ] (=AB a =BB for attributes) - in which the type [t] will include a type [M= yset.t] and the definitions of this module will make use, as much as possib= le, of those defined in [Myset]. >=20 > Here=92s a first proposal (excluding the Product functor for the moment) = :=20 >=20 > =97=97=97=97 myseta.mli > module type Attr =3D sig type t end >=20 > module type T =3D sig > type elt=20 > type attr > type t=20 > 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 > end >=20 > module Make (E : Set.OrderedType) (A: Attr) : T with type elt =3D E.t and= type attr =3D A.t > =97=97=97=20 >=20 > =97=97=97=97 myseta.ml > module type Attr =3D sig type t end >=20 > module type T =3D sig (* idem myseta.mli *) end >=20 > module Make (E : Set.OrderedType) (A : Attr) =3D struct > 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 (e,a) :: s.a= ttrs } > 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 s.attrs > end > =97=97=97=20 >=20 > In practice, of course the [Attr] signature will include other specificat= ions. > In a sense, this is a =AB has a =BB inheritance : whenever i build a [Mys= eta] module, i actually build a [Myset] sub-module and this module is used = to implement all the set-related operations.=20 > Again, so far, so good. > The problem shows when i try to define the [Product] functor for the [Mys= eta] module : > It=92s signature is similar to that of the [Myset.Product] functor, with = an added sharing constraint for attributes (in fact, we could imagine a mor= e sophisticated scheme for merging attributes but cartesian product is here= ) : >=20 > =97=97=97=97 myset.mli (cont=92d) > module Product (S1: T) (S2: T) : > sig > include T with type elt =3D S1.elt * S2.elt > and type attr =3D S1.attr * S2.attr > val product: S1.t -> S2.t -> t > end > =97=97=97=20 >=20 > Now, here=92s my current implementation >=20 > =97=97=97=97 myset.ml (cont=92d) > module Product > (S1: T) > (S2: T) =3D > struct > 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) > let product s1 s2 =3D > { elems =3D P.product (S1.set_of s1) (S2.set_of s2); > attrs =3D > List.fold_left > (fun acc (e1,a1) -> > List.fold_left (fun acc (e2,a2) -> ((e1,e2),(a1,a2))::acc) a= cc (S2.attrs s2)) > [] > (S1.attrs s1) } > end > =97=97=97=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.Produc= t] functor applied on the two related sub-modules [S1] and [S2] to build th= e product module (named P here) and re-use the [product] function of this m= odule to compute the [elems] component of the result. The other component i= s computed directly.=20 > 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 > 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.=20 > I tried to rewrite the signature of the [Myseta.Product] functor (in [mys= eta.mli]) as : >=20 > module Product (S1: T) (S2: T) : > sig > include T with type elt =3D S1.elt * S2.elt > and type attr =3D S1.attr * S2.attr > and type S.t =3D Myset.Product(S1.S)(S2.S).t (* added const= raint *) > val product: S1.t -> S2.t -> t > end >=20 > but it did not change anything.. >=20 > So my question is : is my diagnostic correct and, if yes, which constrain= t(s) are missing and where; or, conversely, am i completely =AB misusing = =BB the functor mechanisms for implementing this kind of =AB reuse by inclu= sion =BB ?=20 >=20 > Any help will be grealy appreciated : i=92ve been reading and re-reading = about functors for the last two days but have the impression that at this s= tep, things get more and more opaque.. :-S >=20 > In anycase, the source code is here : http://filez.univ-bpclermont.fr/lam= uemlqpm >=20 > Jocelyn >=20 --Apple-Mail=_20C93892-9F28-4EF4-984E-EF6B1D3663E6 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=windows-1252 Hi Nicolas,

Thanks fro your answer.
If i understand correctly, you m= ean that if i write, say :

module type S =3D sig type t val zero: t end
module type T =3D sig type t val zero: t end<= /span>
module Make (X : S) = =3D (struct type t =3D X.t * X.t let zero =3D X.zero, X.zero end : T)
module M1 =3D Make (struc= t type t =3D int let zero =3D 0 end)
module M2 =3D Make (struct type t =3D int let zero =3D 0 end)

then the compiler will never be able to deduce that M1= .t and M2.t are indeed compatible. Am i right ?

I = guess it is because re-use the [Myseta.Product] functor only views the abst= ract types exposed by the [Myset.Make] and [Myset.Product] output signature= s.

Seems therefore i am really stuck :(
=
Jocelyn

Le 6 = juil. 2016 =E0 09:49, Nicolas Ojeda Bar <nicolas.ojeda.bar@lexifi.com> a =E9crit :

Hi Jocelyn

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 OCa= ml module system to deduce that P.t and R.S.t are compatible.  In gene= ral 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 litera= lly the same module.  I don't think you will be able to fix this by ad= ding type sharing constrains.

Cheers
Nic= olas


On Tue, Jul 5, 2016 at 5:25 PM, Jocelyn S=E9rot <Jocelyn.Serot@univ-bpclermont.fr> wrote:
Dear all, 
<= br>
I=92m stuck with a problem related with the use of functors f= or implementing a library.
The library concerns Labeled Transitio= n Systems but i=92ll present it in a simplified version using sets.

Suppose i have a (very simplified !) Set module, which i = will call Myset to distinguish from that of the standard library :

=97= =97=97=97 myset.mli
module type T =3D sig
  type elt 
  type t 
  val emp= ty: t
&nbs= p; val add: elt -> t -> t
  val elems: t -> elt list
<= font face=3D"Courier" style=3D"font-size:11px">  val fold: (elt -> = 'a -> 'a) -> t -> 'a -> 'a
end

module Make (E : Set.OrderedType) : T with type elt =3D= E.t
=97=97=97 

=97=97=97=97 myset.ml
module type T =3D sig&nbs= p;=85 (* idem myset.mli *) end

module Make (E : Set.OrderedTyp= e) =3D struct
  module Elt =3D E
  type elt =3D E.t<= /font>
&nbs= p; type t =3D { elems: elt list; }  
  let empty =3D { elems = =3D [] }
  let add q s =3D { elems =3D q :: s.elems }  (* obvi= ously wrong, but does not matter here ! *)
  let elems s =3D s.elem= s
  let fold f s z =3D List.fold_left (fun z e -> f e z) z s.ele= ms
end
=97=97=97 

First= , i add a functor for computing the product of two sets :

=97=97= =97=97 myset.mli (cont=92d)
module Product (S1: T) (S2: T) :
sig
  include T with type elt =3D S1.elt * S2.elt
  val p= roduct: S1.t -> S2.t -> t
end
=97=97=97 

=97=97=97=97 myset= .ml (cont=92d)
module Product
  (S1: T)
  (S2: = T) =3D
struct
  module R =3D
    Make = (struct type t =3D S1.elt * S= 2.elt let co= mpare =3D compare end)
    include R
    let product s1 s2 =3D
&n= bsp;     S1.fold
<= span style=3D"font-size:11px">        (fun q1 z ->
           S2.fold
=       =        (fun q2 z -> R.add (q1,q2) z)
   = ;          s2
        &nb= sp;    z)
        s1
    &nbs= p;   R.empty
end
=97=97=97 

H= ere=92s a typical usage of the Myset module : 

=97=97 ex1.ml 
module Int= Set =3D Myset.Make (struct type t =3D int let compare =3D compare end)
m= odule StringSet =3D Myset.Make (struct type t =3D string let compare =3D co= mpare end)

let s1 =3D IntSet.add 1 (IntSet.add 2 IntSet.empty)
let s2 =3D StringSet.add "a" (StringSet.add "b" StringSet.empty)

module IntStringSet =3D Myset.Product (IntSet) (StringSet)=
let s3 =3D IntStringSet.product s1 s2
=97=97

So far, so good. 

Now suppose i want to =AB augment =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 fil= es [myset.ml] and [myset= .mli]. But suppose i want to reuse as much as possible the code already wri= tten. My idea is define a new module - let=92s call it [myseta] (=AB a=  =BB for attributes) - in which the type [t] will include a type [Myse= t.t] and the definitions of this module will make use, as much as possible,= of those defined in [Myset].

Here=92s a first pro= posal (excluding the Product functor for the moment) : 

=
=97= =97=97=97 myseta.mli
module type Attr =3D sig type t end
module type T =3D sig
=   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
end

module Make (E : Set.OrderedType) (A: Attr)= : T with type elt =3D E.t and type attr =3D A.t
<= div>=97=97=97 

=97=97=97=97 myseta.ml
module type Attr =3D sig type t end

= module type T =3D sig (* idem myseta.mli *) end
module Ma= ke (E : Set.OrderedType) (A : Attr) =3D struct
  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) li= st }
  let empty =3D { elems =3D S.empty; attrs =3D [] }
  = let add (e,a) s =3D { elems =3D S.add e s.elems; attrs =3D (e,a) :: s.attrs= }
  let elems s =3D S.elems s.elems
  let attrs s =3D s.at= trs
  let set_of s =3D s.elems
  let fold f s z =3D List.= fold_left (fun z e -> f e z) z s.attrs
end
<= div>=97=97=97 

In practice, of course the [Attr] s= ignature will include other specifications.
In a sense, this is a= =AB has a =BB inheritance : whenever 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=92s signature is similar to that of the [My= set.Product] functor, with an added sharing constraint for attributes (in f= act, we could imagine a more sophisticated scheme for merging attributes bu= t cartesian product is here) :

=97=97=97=97 myset.mli (cont= =92d)
module Product (S1: T) (S2: T) :
sig
  include T w= ith type elt =3D S1.elt * S2.elt
          &nbs= p;  and type attr =3D S1.attr * S2.attr
  val product: S1.t ->= S2.t -> t
end
=97=97=97 

Now, here=92s my current implementation

=97=97=97=97 myset.ml (cont=92d)
mo= dule Product
  (S1: T)
  (S2: T) =3D
struct
  mo= dule R =3D
    Make
      (struct type t =3D= S1.elt * S2.elt let compare =3D compare end)
      (stru= ct type t =3D S1.attr * S2.attr let compare =3D compare end)<= /div>
  incl= ude R
  module P =3D Myset.Product(S1.S)(S2.S)
  let product s1 s2 =3D
  &= nbsp; { elems =3D P.product (S1.set_of s1) (S2.set_of s2);
            attrs =3D
        List.fo= ld_left
          (fun acc (e1,a1) ->=
&nb= sp;            List.fold_left (fun acc (e2,a2) -&g= t; ((e1,e2),(a1,a2))::acc) acc (S2.attrs s2))
          []
    =       (S1.attrs s1) }
end
<= span style=3D"font-size:11px;font-family:Courier">=97=97=97 

I use the [Myseta.Make] functor for building t= he resulting module [named R here]. For defining the [product] function, i = first use the [Myset.Product] functor applied on the two related sub-module= s [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 re= sult. The other component is computed directly. 
The problem= is that when i try to compile this i get this message : 
File "= myseta.ml", line 44, characters 14-53:
Error: This exp= ression has type P.t =3D Myset.Product(S1.S)(S2.S).t
 = ;      but an expression was expected of type S.t =3D R.S.t<= /i>

My intuition is that a sharing co= nstraint is missing somewhere but i just cannot figure out where to add it.=  
I tried to rewrite the signature of the [Myseta.Product] f= unctor (in [myseta.mli]) as :

module Product (S1: T) (S2: T) :
= sig
  include T with type elt =3D S1.elt * S2.elt
    =          and type attr =3D S1.attr * S2.attr
&n= bsp;            and type S.t =3D Myset.Produc= t(S1.S)(S2.S).t  (* added constraint *)
  val product: S1.t -&= gt; S2.t -> t
end

but it= did not change anything..

So my question is : is = my diagnostic correct and, if yes, which constraint(s) are missing and wher= e; or, conversely, am i completely =AB misusing =BB the functor m= echanisms for implementing this kind of =AB reuse by inclusion = =BB ? 

Any help will be grealy appreciated : = i=92ve 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

In anycase, the source code is here : http:/= /filez.univ-bpclermont.fr/lamuemlqpm

Jocelyn


= --Apple-Mail=_20C93892-9F28-4EF4-984E-EF6B1D3663E6--