From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id q2EN1QB9026775 for ; Thu, 15 Mar 2012 00:01:26 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AnADAAkjYU/RVdK2kWdsb2JhbABDpFiRVggiAQEBAQkJDQcSKYIJAQEBBBICExkBGxILAQMMBgULDQ0hIgERAQUBChIGEwgKCQeHaAugIAqMEIJxhS4/gQwBBQuQdASVVo5JPYQJ X-IronPort-AV: E=Sophos;i="4.73,586,1325458800"; d="scan'208";a="149432292" Received: from mail-iy0-f182.google.com ([209.85.210.182]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 15 Mar 2012 00:01:07 +0100 Received: by mail-iy0-f182.google.com with SMTP id k25so4805631iah.27 for ; Wed, 14 Mar 2012 16:01:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; bh=7GAmOKw3ogzkWnUpoyUUhEWlNt+hlTutgK9VoGdjpZI=; b=p3OjI48ykNbRz5PBACuHrtzeeiBR7r+ndvIav63/MRJ3qdIPwmwAkJNDwmg2fnfdsR xfC1eZ4AqO08cxAI9o1wv1KVTU+LnO6KgqEsrXb2oEpfLh6ZS7LsX8PHeistYibslgty +KpLw/vQ+1bYzL3IPPv7FoXPhtEHPkXACKYPbRUoHp3BdoL/zFdQ19741MW10whhdbY5 iOAsEbluolA2633u728bmUWH6RXXG+fNJ5xrcc8cSp6+kjOe5d1Ts6GSBbu+H88qT3O+ 8oE0GycrI0j/VokQH9nJ0zsc4M/USyp8kYcsp/P0BqeRfX5Sl2NpSvTjVu10itu3MpA5 6kVQ== Received: by 10.50.181.194 with SMTP id dy2mr7288009igc.48.1331766067831; Wed, 14 Mar 2012 16:01:07 -0700 (PDT) MIME-Version: 1.0 Received: by 10.50.3.38 with HTTP; Wed, 14 Mar 2012 16:00:27 -0700 (PDT) In-Reply-To: <20120314201221.GA13221@zed.irill.org> References: <20120314201221.GA13221@zed.irill.org> From: Gabriel Scherer Date: Thu, 15 Mar 2012 00:00:27 +0100 Message-ID: To: Pietro Abate Cc: caml-list@inria.fr Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by walapai.inria.fr id q2EN1QB9026775 Subject: Re: [Caml-list] Arrays and private types Here is a proposal: https://gitorious.org/gasche-snippets/private-array-keys-type/blobs/master/private_array_key_types.ml It works by using a functor to generate "fresh" private types for keys. Note that the arrays themselves are still polymorphic (no IntArray FloatArray etc.). The user still has to use the discipline to produce a new application of ArrayMake each time she wants to use a different kind of array: if she only does `module A = ArrayMake(struct end)` and then use `A` for everything, there will be no additional safety guarantee. On Wed, Mar 14, 2012 at 9:12 PM, Pietro Abate wrote: > hello world. > > In my application I'm using arrays all over, and lately I've discovered a > couple of bugs related to the fact that I was using the index of one array to > get the element of another array. Since both indexes are int the compiler could > not help me at all. Using private types it seems I can solve this problem > without loosing anything (??). > > This is what I came up with ... and since, I was at it I've also restricted > the type of the Array... > > my questions are : > > - Is there a better way of doing it, such that the type of IntArray is not >  IntArray.T.t array but rather int array ? >  Consider that I'm going to this deal of trouble only because I want to define >  the Array signature (with the private annotation) only once and not for each >  type of array I want to instantiate ... > > - how can avoid this problem ? > # let a = IntArray.make 10 0 ;; > val a : IntArray.T.t array = [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|] > # a.(1);; > - : IntArray.T.t = 0 > # > # IntArray.get a 1 ;; > Error: This expression has type int but an expression was expected of type >         IntArray.t > >  Ideally I'd like the same type of error when using a.(1) ... > > > thanks >        pietro > > ------------------- > > module type T = sig type t end > > module MakePrivateArraySig (T : T) = struct >  module type Sig = sig >    type t = private int >    val of_int : int -> t >    val to_int : t -> int >    val length : T.t array -> int >    val get : T.t array -> t -> T.t >    val set : T.t array -> t -> T.t -> unit >    val make : int -> T.t -> T.t array >    val create : int -> T.t -> T.t array >    val init : int -> (t -> T.t) -> T.t array >    val append : T.t array -> T.t array -> T.t array >    val concat : T.t array list -> T.t array >    val to_list : T.t array -> T.t list >    val of_list : T.t list -> T.t array >    val iter : (T.t -> unit) -> T.t array -> unit >    val map : (T.t -> 'b) -> T.t array -> 'b array >    val iteri : (t -> T.t -> unit) -> T.t array -> unit >    val mapi : (t -> T.t -> 'b) -> T.t array -> 'b array >    val fold_left : (T.t -> 'b -> T.t) -> T.t -> 'b array -> T.t >    val fold_right : (T.t -> 'b -> 'b) -> T.t array -> 'b -> 'b >    val unsafe_get : T.t array -> int -> T.t >    val unsafe_set : T.t array -> int -> T.t -> unit >  end > end > > module type IntArrayType = sig >  module T : sig type t = int end >  include MakePrivateArraySig(T).Sig > end > > module type FloatArrayType = sig >  module T : sig type t = float end >  include MakePrivateArraySig(T).Sig > end > > module IntArray : IntArrayType = struct >  type t = int >  module T = struct type t = int end >  include Array >  let of_int x = x >  let to_int x = x > end > > module FloatArray : FloatArrayType = struct >  type t = int >  module T = struct type t = float end >  include Array >  let of_int x = x >  let to_int x = x > end > > ----------------------- > This is clearly the solution for the first question, but I'll be forced to > write a signature for each array ... I "feel" that there is a clean way of > doing this ... > > ----------------------- > > module StringArray : Sig = struct >  type t = int >  include Array >  let of_int x = x >  let to_int x = x >  end >  ;; > module type Sig = >  sig >    type t = private int >    val of_int : int -> t >    val to_int : t -> int >    val length : string array -> int >    val get : string array -> t -> string >    val set : string array -> t -> string -> unit >    val make : int -> string -> string array >    val create : int -> string -> string array >    val init : int -> (t -> string) -> string array >    val append : string array -> string array -> string array >    val concat : string array list -> string array >    val to_list : string array -> string list >    val of_list : string list -> string array >    val iter : (string -> unit) -> string array -> unit >    val map : (string -> 'a) -> string array -> 'a array >    val iteri : (t -> string -> unit) -> string array -> unit >    val mapi : (t -> string -> 'a) -> string array -> 'a array >    val fold_left : (string -> 'a -> string) -> string -> 'a array -> string >    val fold_right : (string -> 'a -> 'a) -> string array -> 'a -> 'a >    val unsafe_get : string array -> int -> string >    val unsafe_set : string array -> int -> string -> unit >  end > > # let c = StringArray.make 10 "a";; > val c : string array = [|"a"; "a"; "a"; "a"; "a"; "a"; "a"; "a"; "a"; "a"|] > # StringArray.set c 1 "aa";; > Error: This expression has type int but an expression was expected of type >         StringArray.t > # StringArray.set c (StringArray.of_int 1) "aa";; > - : unit = () > # c;; > - : string array = [|"a"; "aa"; "a"; "a"; "a"; "a"; "a"; "a"; "a"; "a"|] > # > > -- > Caml-list mailing list.  Subscription management and archives: > https://sympa-roc.inria.fr/wws/info/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs >