[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Pierre Weis <Pierre.Weis@i...> |
| Subject: | Re: addressable_to_list |
> The following ocaml function converts a string to a list:
> (which btw, I guess should be in the String module)
This has been discussed many times in this list. We always ended up with
the following conclusion:
1) This function is trivial to implement
2) This way of dealing with strings is inefficient and should not be
encouraged in the core library.
[...]
> However, what I'd like to be able to do this for any countable thing.
>
> e.g
>
> let nthable_to_list s fnth flen =
> let len = flen s in
> let rec scan n =
> if n < len then
> fnth s n :: scan (n + 1)
> else
> []
> in
> scan len
>
> Then one can of course simulate the first code snippit with:
>
> let string_of_list s = nthable_to_list s (fun s n -> s.[n]) (fun s -> String.length s)
>
> I know how this is done in Haskell, but how do something like it in O'caml?
What's the problem with your code ? It looks pretty neat to me :)
[...]
>
> While I'm on the subject of array initialisers, the
> new safe array creation could be improved. From memory,
> it takes a function which takes an int and
> returns an initialisation element. It would be better
> if the counting was left upto the user supplied function
> and the output was fed back into the input. e.g like foldr.
> e.g
>
> ('a -> 'b * 'a) -> 'b array
>
> 1.. initialisation would then look like
>
> (fun x -> x, x+1)
This has been discussed in a thread named reference initialization
2 months ago. We ended up with a pretty general higher-order
initialization function:
(*
[initialize n f] returns a fresh array of length [n],
with elements initialized by function [f].
All the elements of the new array must be assigned once and only
once by the function [f]. [f] received two functions as arguments,
one to access elements of the new array, and the other to set the
elements of the new array. [f] can access to element [i] of the new
array provided [f] has already properly initialized element [i].
Raise [Not_yet_initialized i] if element [i] is accessed before being
assigned.
Raise [Already_initialized i] if element [i] is assigned twice.
Raise [Never_initialized i] if element [i] has never been assigned at
the end of initialization.
[Array.initialize n f] uses [2 n] words of heap space.
*)
exception Not_yet_initialized of int;;
exception Already_initialized of int;;
exception Never_initialized of int;;
(*
val initialize :
int -> ((int -> 'a) -> (int -> 'a -> unit) -> unit) -> 'a array
*)
let initialize n f =
if n = 0 then [||] else
let init_v = Array.make n false in
let v = ref [||] in
let get i = if init_v.(i) then !v.(i) else raise (Not_yet_initialized i) in
let set i ei =
if !v = [||] then v := Array.make n ei;
if not init_v.(i) then (!v.(i) <- ei; init_v.(i) <- true) else
raise (Already_initialized i) in
(f get set : unit);
for i = 0 to n - 1 do if not init_v.(i) then raise (Never_initialized i) done;
!v;;
>From this initialization function, you can easily define your array
initializer:
let ja_initialize n f =
let ja_init get set =
let rec init i =
let e, j = f i in
set i e;
init j in
init 0 in
initialize n ja_init;;
val ja_initialize : int -> (int -> 'a * int) -> 'a array = <fun>
You'll still have the good properties of complete and unique
initialization that initialize ensures.
Pierre Weis
INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://cristal.inria.fr/~weis/