Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Give example usage for BatEnum.clump #882

Open
blaiseli opened this issue Nov 9, 2018 · 4 comments
Open

Give example usage for BatEnum.clump #882

blaiseli opened this issue Nov 9, 2018 · 4 comments

Comments

@blaiseli
Copy link

blaiseli commented Nov 9, 2018

I fail to understand how to use BatEnum.clump and whether it is actually what I need (I want to process an enum four elements by four elements). It would be nice to have more examples in the documentation.

@gasche
Copy link
Member

gasche commented Nov 11, 2018

clump can be used for this but the API will not be very convenient: it will call a ('a -> unit) function on each of the four elements in turn, so unless your processing is a rather simple accumulation/aggregation it can be painful to use.

I would use either group or the combination of take (get the four elements, as an enum) and drop (drop the first four elements, and work on the rest). The nicest tool for your needs would be split_at : int -> 'a t -> 'a t * 'a t, which returns an enumeration of the first N elements and an enumeration of the rest, but unfortunately it is available in List and LazyList but not Enum or Seq (which I would prefer over Enum for most needs, as it is simpler to use and reason about, and faster).

@gasche
Copy link
Member

gasche commented Nov 11, 2018

(Your suggestion of including examples is excellent and not yet resolved.)

@blaiseli
Copy link
Author

Thanks for your suggestions. I ended up doing things by using BatEnum.from on a function that does four BatEnum.get.

It works, but ways to improve speed would be welcome. So I looked at Seq, but I'm not sure I can go that way because of this:

Since enumerations are consumable and sequence are not, it is not possible to have the inverse operations, i.e. of_enum

The Enum I'm working with comes from BatIO.lines_of BatIO.stdin. Is there a better way of processing stdin line by line ?

@UnixJunkie
Copy link
Member

Maybe:

let lines_of_file (fn: filename): string list =
  with_in_file fn (fun input ->
      let res, exn = BatList.unfold_exc (fun () -> input_line input) in
      if exn <> End_of_file then
        raise exn
      else res
    )

or

(* call f on lines of file *)
let iter_on_lines_of_file fn f =
  let input = open_in_bin fn in
  try
    while true do
      f (input_line input)
    done
  with End_of_file -> close_in input

or

(* map f on lines of file *)
let map_on_lines_of_file (fn: filename) (f: string -> 'a): 'a list =
  with_in_file fn (fun input ->
      let res, exn = L.unfold_exc (fun () -> f (input_line input)) in
      if exn = End_of_file then res
      else raise exn
    )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants