Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] stream conversion
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jean-Baptiste Rouquier <jean-baptiste.rouquier@e...>
Subject: Re: [Caml-list] stream conversion
Dustin Sallings <dustin@spy.net> wrote:

>I have a need to convert a ``string stream'' to a ``char stream.''
>
Small is beautiful !
#load "camlp4o.cma";;
let rec convert = parser
  | [< 'string; stream >] -> [<Stream.of_string string; convert stream>]
  | [<>] -> [<>]

(* That's it... However this function compiles but doesn't work.*)
(* Can anybody explain the following problem: *)
let foo = [< Stream.of_string "bar"; Stream.of_string "quz">]
let _ = Stream.next foo
(* Exception: Failure "illegal stream concatenation". *)




(* So I have to implement my own (awful : skip it!) concatenation 
function : *)
let concat s s' =
  let stream_next =
    let rec f = ref (fun _ ->
      try Some (Stream.next s)
      with Stream.Failure ->
    Printf.printf "redefining f\n%!";
    f := (fun _ ->
        (try Some (Stream.next s')
         with Stream.Failure -> None));
    !f 0) in
    fun x -> !f x
  in Stream.from stream_next


(* And then slightly rewrite my function : *)

let rec convert = parser
  | [< 'string; stream >] -> concat (Stream.of_string string) (convert 
stream)
  | [<>] -> [<>]



(*let's test it*)
let foo = convert (Stream.of_list ["foo"; "bar"; ""; "qux"])

let _ = Stream.next foo;;
  (* - : char = 'f' *)
let _ = Stream.next foo;;
  (* - : char = 'o' *)
let _ = Stream.next foo;;
  (* - : char = 'o' *)
let _ = Stream.next foo;;
  (* redefining f *)
  (* - : char = 'b' *)
let _ = Stream.next foo;;
  (* - : char = 'a' *)
let _ = Stream.next foo;;
  (* - : char = 'r' *)
let _ = Stream.next foo;;
  (* redefining f *)
  (* redefining f *)
  (* - : char = 'q' *)
let _ = Stream.next foo;;
  (* - : char = 'u' *)
let _ = Stream.next foo;;
  (* - : char = 'x' *)
let _ = Stream.next foo;;
  (* redefining f *)
  (* Exception: Stream.Failure. *)


Except the concatenation problem, I think camlp4 makes it much clearer, 
and it works with empty strings.

Jean-Baptiste Rouquier.

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners