Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
* addressable_to_list
@ 2000-07-26 14:13 Julian Assange
  2000-07-26 21:35 ` addressable_to_list Julian Assange
  2000-07-28 14:46 ` addressable_to_list Pierre Weis
  0 siblings, 2 replies; 3+ messages in thread
From: Julian Assange @ 2000-07-26 14:13 UTC (permalink / raw)
  To: caml-list; +Cc: proff


The following ocaml function converts a string to a list:
(which btw, I guess should be in the String module)

let string_to_list s =
  let len = String.length s in
  let rec scan n =
    if n < len then
      s.[n] :: scan (n + 1)
    else
      []
  in
    scan len

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?

A couple of useful string functions that are missing:

        conversion, strings <-> bigarrays of chars a bigarry like
        create function, which takes a function argument. (regular
        Array's also have the same problem). String has functions to
        create an empty, constant filled string, or an uninitialised
        string. This is pretty important, because Digest for instance,
        only takes strings.

        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)


Cheers,
Julian.



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

* Re: addressable_to_list
  2000-07-26 14:13 addressable_to_list Julian Assange
@ 2000-07-26 21:35 ` Julian Assange
  2000-07-28 14:46 ` addressable_to_list Pierre Weis
  1 sibling, 0 replies; 3+ messages in thread
From: Julian Assange @ 2000-07-26 21:35 UTC (permalink / raw)
  To: Julian Assange; +Cc: caml-list

nb. don't post to caml-list after four classes of South Australian merlot.

string_of_list should be list_of_string

"scan len" should be "scan 0"

etc

Correcting the human language is too embarressing.

Cheers,
Julian.



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

* Re: addressable_to_list
  2000-07-26 14:13 addressable_to_list Julian Assange
  2000-07-26 21:35 ` addressable_to_list Julian Assange
@ 2000-07-28 14:46 ` Pierre Weis
  1 sibling, 0 replies; 3+ messages in thread
From: Pierre Weis @ 2000-07-28 14:46 UTC (permalink / raw)
  To: Julian Assange; +Cc: caml-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/




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

end of thread, other threads:[~2000-07-28 14:49 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-07-26 14:13 addressable_to_list Julian Assange
2000-07-26 21:35 ` addressable_to_list Julian Assange
2000-07-28 14:46 ` addressable_to_list Pierre Weis

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