On Fri, Jun 26, 2009 at 10:26 AM, Erick
Tryzelaar<idade...@users.sourceforge.net> wrote:
> On Jun 26, 2009, at 4:36 AM, john skaller wrote:
>
>> I don't like the STL iterator stuff much for Felix.
>
> Yeah, I never was too fond of it either. It's really cool that we can
> do this, but since I at least lean towards more functional-style
> interfaces, I didn't see myself using them that often. Oleg had a
> paper about this very problem, the whole internal vs external iterators:
>
> http://okmij.org/ftp/papers/LL3-collections-enumerators.txt
>
> I wonder if we could draw any inspiration from it.


I found a partial ocaml implementation of this:

http://www.reddit.com/r/programming/comments/1t1s3/whats_wrong_with_iterators_cursors_or/

I fleshed it out into a full example. It will print out:

enumerator: cba
cursor: c
cursor: b
cursor: a


module type FOLDABLE =
sig
  type 'a t
  val fold : ('a -> 'b Lazy.t -> 'b) -> 'b -> 'a t -> 'b
end

module type CURSOR =
sig
  type 'a t
  type 'a cursor

  val make : 'a t -> 'a cursor
  val next : 'a cursor -> ('a * 'a cursor) option
end

module MakeCursor (F : FOLDABLE) : CURSOR with type 'a t = 'a F.t =
struct
  type 'a t = 'a F.t

  type 'a cursor =
    | Done
    | Next of 'a * 'a cursor Lazy.t

  let make coll =
    F.fold (fun x rest_cursor -> Next(x, rest_cursor)) Done coll

  let next c =
    match c with
    | Done -> None
    | Next(x, cl) -> Some(x, Lazy.force cl)
end

module L =
struct
  type 'a t = 'a list

  let fold f init rest =
    let rec aux init rest =
      match rest with
      | [] -> init
      | head :: tail -> aux (f head (lazy init)) tail
    in
    aux init rest

  let fold_left f init rest =
    fold (fun init rest -> f init (Lazy.force rest)) init rest
end
;;


print_endline ("enumerator: " ^ L.fold_left (fun x rest -> x ^ rest)
"" ["a"; "b"; "c"]);;

module C = MakeCursor(L);;

let c = C.make ["a"; "b"; "c"];;

let c =
  match C.next c with
  | None -> c
  | Some (x, c) -> print_endline ("cursor: " ^ x); c
;;

let c =
  match C.next c with
  | None -> c
  | Some (x, c) -> print_endline ("cursor: " ^ x); c
;;

let c =
  match C.next c with
  | None -> c
  | Some (x, c) -> print_endline ("cursor: " ^ x); c
;;

let c =
  match C.next c with
  | None -> c
  | Some (x, c) -> print_endline ("cursor: " ^ x); c
;;

------------------------------------------------------------------------------
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to