c-cube/gen

skipping

nilsbecker opened this issue · 6 comments

i have not found a way to take only every nth element -- is this possible? have i missed it? more generally, one could think of a list of 'step lengths' or 'skip lengths' to apply cyclically as one moves over the generator, i.e. [0;2;1] means 'take next element, then skip two and take one, then skip one and take one, then take the next element, etc.,..'

right now i am using chunks together with Array.get which seems not ideal.

I think skip would be useful (it's pretty simple to write I think, with a tiny state machine). The more general version makes me more dubious, it seems hard to explain and rarely useful. Skip could look like:

let skip n gen =
  let i = ref n in
  let rec next() =
    match gen() with
    | None -> None
    | Some x when !i = 1 ->
      i := n; Some x
    | Some _ ->
      decr i; next()
  in next

i would agree that the simple one is probably enough in >90% of the cases. the more general one just occurred to me by imagining a scenario like "i need successive pairs which occur every 7 elements" or something like that. however, then one could probably just use chunks and pay for array construction. another way of implementing general skipping would be to zip together two generators; one for the jump lengths and another one for the value stream. again, probably not widely useful.

about naming: skip 4 to me means that every 5th element should be taken. so one has to be careful; maybe skip is not a good name, despite its ubiquity

take_every ~nth:5 ?

that's very clear i find. one could argue that take_every 5 is already enough but i guess that's taste