From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.1.3 Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id 60ACCBB84 for ; Wed, 27 Aug 2008 15:09:26 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ar0CAAjvtEiCNhABiGdsb2JhbACSMwEBAQ8gpk+BZw X-IronPort-AV: E=Sophos;i="4.32,279,1217800800"; d="scan'208";a="16320474" Received: from discorde.inria.fr ([192.93.2.38]) by mail3-smtp-sop.national.inria.fr with ESMTP; 27 Aug 2008 15:09:26 +0200 Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id m7RD9PV6006839 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Wed, 27 Aug 2008 15:09:25 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ar0CAAjvtEiCNhABiGdsb2JhbACSMwEBAQ8gpk+BZw X-IronPort-AV: E=Sophos;i="4.32,279,1217800800"; d="scan'208";a="16320472" Received: from kurims.kurims.kyoto-u.ac.jp ([130.54.16.1]) by mail3-smtp-sop.national.inria.fr with ESMTP; 27 Aug 2008 15:09:23 +0200 Received: from localhost (orion [130.54.16.5]) by kurims.kurims.kyoto-u.ac.jp (8.13.8/8.13.8) with ESMTP id m7RD9F6v028081; Wed, 27 Aug 2008 22:09:16 +0900 (JST) Date: Wed, 27 Aug 2008 22:09:15 +0900 (JST) Message-Id: <20080827.220915.68542765.keiko@kurims.kyoto-u.ac.jp> To: jeremie.lumbroso@etu.upmc.fr Cc: caml-list@inria.fr Subject: Re: [Caml-list] Separating two mutually recursive modules From: Keiko Nakata In-Reply-To: <2b7b425b0808230940r58c6d4f6t6b06f12a2e1bb52b@mail.gmail.com> References: <2b7b425b0808210400j618e461fre54f73612b920e4a@mail.gmail.com> <20080822.175619.125115724.keiko@kurims.kyoto-u.ac.jp> <2b7b425b0808230940r58c6d4f6t6b06f12a2e1bb52b@mail.gmail.com> X-Mailer: Mew version 4.2 on Emacs 20.7 / Mule 4.1 (AOI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Miltered: at discorde with ID 48B55205.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; recursive:01 typechecker:01 ocaml's:01 applicative:01 functors:01 variants:01 flags:01 variants:01 sig:01 sig:01 functor:01 node:01 val:01 struct:01 val:01 Hello. > I know of the "double vision" problem, and I am actually confused by > the post which you reference. I think it discusses an old version of > the typechecker, as the example which Xavier Leroy gives supposedly to > illustrate the flaw now (3.10.2) properly type-checks: Yes; I was forgetting the fix. Sorry for confusing you. But I believe the previous program I posted should type check, so I am not sure whether the fix is complete. Furthermore, I may suspect the problem there has something to do with OCaml's way of handling applicative functors; I am not sure though. For what it's worth, I managed to type check my previous attempt, which is attached below; the trick is to add the manifest type specification "type t = Boxes.T.t" to the signature of the module T. Unfortunately, I do not know exactly why this trick works. > XL also mentions a solution for this problem: resorting to variants, > so Caml explicitly flags the type, thus preventing it from > "forgetting" how a given type was defined. > > I wonder if the specific problem which was solved by this hack still > exists (and if it is in fact the problem that I'm encountering here). > > Do you (or anybody else) have any idea (if I can /) how to adapt the > "variant hack" to my problem ... I have tried it by wrapping the type t of module T with variants, but I could not make it type check. Maybe I did it wrongly. With best, Keiko -------------------------------- module type BOXES_PROVIDER = sig module T : sig type t end end module type FVALIDATOR = functor(Boxes: BOXES_PROVIDER) -> sig type t = Me of int | Node of t * t | B of Boxes.T.t val fold_on_B : (Boxes.T.t -> 'a) -> ('a -> 'a -> 'a) -> 'a -> t -> 'a end module BoxesProvider(FValidator : FVALIDATOR) : sig module Boxes : BOXES_PROVIDER end = struct module rec Validator : sig type t val fold_on_B : (Boxes.T.t -> 'a) -> ('a -> 'a -> 'a) -> 'a -> t -> 'a end = FValidator(Boxes) and Boxes : sig module T: sig type t end end = struct module rec T : sig type t = Boxes.T.t val o_f : ('a -> bool) -> ('a -> bool) -> t -> bool end = struct type t = T of B.t let o_f p1 p2 = function T x -> B.o_f p1 p2 x end and A : sig type t = | Anil| Aout of Validator.t val o_f : ('a -> bool) -> ('a -> bool) -> t -> bool end = struct type t = | Anil | Aout of Validator.t let o_f p1 p2 = let rec aux = function | Anil -> false | Aout tv -> Validator.fold_on_B (fun x -> T.o_f p1 p2 x) (||) false tv in aux end and B : sig type t = Bnil | Bout of A.t * t val o_f : ('a -> bool) -> ('a -> bool) -> t -> bool end = struct type t = Bnil | Bout of A.t * t let o_f p1 p2 = let rec aux = function | Bnil -> false | Bout(a, tv) -> (A.o_f p1 p2 a) || (aux tv) in aux end end end module FValidator(Boxes: BOXES_PROVIDER) : sig type t = Me of int | Node of t * t | B of Boxes.T.t val fold_on_B : (Boxes.T.t -> 'a) -> ('a -> 'a -> 'a) -> 'a -> t -> 'a end = struct type t = Me of int | Node of t * t | B of Boxes.T.t let fold_on_B f combinator default = let rec aux = function | Node(b1, b2) -> combinator (aux b1) (aux b2) | B r -> f r | _ -> default in aux end module Boxes = BoxesProvider(FValidator)