From: Pietro Abate <Pietro.Abate@pps.jussieu.fr>
To: caml-list@inria.fr
Subject: [Caml-list] Arrays and private types
Date: Wed, 14 Mar 2012 21:12:21 +0100 [thread overview]
Message-ID: <20120314201221.GA13221@zed.irill.org> (raw)
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"|]
#
next reply other threads:[~2012-03-14 20:13 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-14 20:12 Pietro Abate [this message]
2012-03-14 23:00 ` Gabriel Scherer
2012-03-15 11:04 ` Pietro Abate
2012-03-15 13:18 ` Gabriel Scherer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120314201221.GA13221@zed.irill.org \
--to=pietro.abate@pps.jussieu.fr \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox