Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
* [Caml-list] Arrays and private types
@ 2012-03-14 20:12 Pietro Abate
  2012-03-14 23:00 ` Gabriel Scherer
  0 siblings, 1 reply; 4+ messages in thread
From: Pietro Abate @ 2012-03-14 20:12 UTC (permalink / raw)
  To: caml-list

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"|]
# 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-03-15 13:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-14 20:12 [Caml-list] Arrays and private types Pietro Abate
2012-03-14 23:00 ` Gabriel Scherer
2012-03-15 11:04   ` Pietro Abate
2012-03-15 13:18     ` Gabriel Scherer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox