From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: weis Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id TAA06907 for caml-redistribution; Fri, 29 Oct 1999 19:07:30 +0200 (MET DST) Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id KAA08126 for ; Fri, 29 Oct 1999 10:46:35 +0200 (MET DST) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by concorde.inria.fr (8.8.7/8.8.7) with ESMTP id KAA09263; Fri, 29 Oct 1999 10:46:20 +0200 (MET DST) Received: (from xleroy@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id KAA29642; Fri, 29 Oct 1999 10:46:20 +0200 (MET DST) Message-ID: <19991029104620.42535@pauillac.inria.fr> Date: Fri, 29 Oct 1999 10:46:20 +0200 From: Xavier Leroy To: luther@dpt-info.u-strasbg.fr, caml-list@inria.fr Subject: Re: module, module type et foncteurs, ... References: <19991022160304.A27175@maxime.u-strasbg.fr> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Mailer: Mutt 0.89.1 In-Reply-To: <19991022160304.A27175@maxime.u-strasbg.fr>; from Sven LUTHER on Fri, Oct 22, 1999 at 04:03:04PM +0200 Sender: weis > [Erreur mystérieuse avec des foncteurs:] > Type declarations do not match: > type b = Make_B(A).b = | TA of A.a | TB of b > is not included in > type b = | TA of A.a | TB of b Le message d'erreur est justifié, mais difficile à comprendre car en fait tu as deux modules différents qui s'appellent tous deux "A" avec tous deux une composante de type "a", et le typeur est juste en train de te dire que les deux types "A.a" sont différents. Reprenons: > module A = struct > type a = A | B | C > let id (x : a) = x > end Ça, c'est ton premier module A. > module type T_A = sig > type a > val id : a -> a > end > module type T_A_detail = sig > type a = A | B | C > end > module type T_A_choisi = T_A > module type T_B = sig > type a > type b = > | TA of A.a > | TB of b > end Remarquons que T_B fait référence au premier module A. > module type T_Make_B = functor (A : T_A_choisi) -> T_B Là, tu introduis un second module A qui est le paramètre du foncteur, mais l'occurrence de A.a dans T_B fait toujours référence au premier module A. > module Make_B (A : T_A_choisi) = struct > type a = A.a > type b = > | TA of A.a > | TB of b > end Par conséquent, Make_B n'a pas le type T_Make_B, mais plutôt functor (A : T_A_choisi) -> sig type a type b = | TA of A.a | TB of b end où A.a fait maintenant référence au paramètre du foncteur. > module Make_C (A : T_A_detail) (Make_B : T_Make_B) = struct > let string_of_a = function > | A.A -> "A" > | A.B -> "B" > | A.C -> "C" > end > module B2 = Make_B (A) > module C2 = Make_C (A) (Make_B) C'est normal que ça fasse une erreur puisque Make_B n'est pas du type T_Make_B attendu par Make_C. > Je ne comprend pas qu'elle est la difference entre > type b = Make_B(A).b = | TA of A.a | TB of b > et > type b = | TA of A.a | TB of b Le premier type contient plus d'infos que le second: on sait que non seulement il a des constructeurs TA et TB avec les types indiqués, mais que de plus il est compatible avec Make_B(A).b. En temps normal (si les deux occurrences de A.a sont bien le même type!), la première déclaration est "sous-type" de la seconde, puisqu'on peut toujours oublier l'info supplémentaire. > D'un autre cote est-ce qu'un type de tableau de booleens qui serait > represente de maniere efficace existe ? on aurrait un bit par > booleen, et non un int comme cela est fait actuellement. J'imagine > qu'on peut faire cela en definissant un type de tableau d'entier, et > aller voir la valeur de chaque bit de ces entiers. Il n'y a pas (encore?) de module de bibliothèque qui fasse cela, mais c'est en effet facile à implémenter. Mieux vaut utiliser une chaîne de caractères qu'un tableau d'entiers (31 ou 63 bits), cependant. - Xavier Leroy