title: F#: How do i split up a sequence into a sequence of sequences
body: <p><strong>Background:</strong> </p>
  
  <p>I have a sequence of contiguous, time-stamped data. The data-sequence has gaps in it where the data is not contiguous. I want create a method to split the sequence up into a sequence of sequences so that each subsequence contains contiguous data (split the input-sequence at the gaps).</p>
  
  <p><strong>Constraints:</strong> </p>
  
  <ul>
  <li>The return value must be a sequence of sequences to ensure that <strong>elements are only produced as needed</strong> (cannot use list/array/cacheing)</li>
  <li>The solution must NOT be O(n^2), probably ruling out a Seq.take - Seq.skip pattern (cf. <a href="https://stackoverflow.com/questions/1306140/f-why-is-using-a-sequence-so-much-slower-than-using-a-list-in-this-example">Brian's</a> post)</li>
  <li>Bonus points for a functionally idiomatic approach (since I want to become more proficient at functional programming), but it's not a requirement.</li>
  </ul>
  
  <p><strong>Method signature</strong></p>
  
  <pre><code>let groupContiguousDataPoints (timeBetweenContiguousDataPoints : TimeSpan) (dataPointsWithHoles : seq&lt;DateTime * float&gt;) : (seq&lt;seq&lt; DateTime * float &gt;&gt;)= ... 
  </code></pre>
  
  <p>On the face of it the problem looked trivial to me, but even employing Seq.pairwise, IEnumerator&lt;_>, sequence comprehensions and yield statements, the solution eludes me. I am sure that this is because I still lack experience with combining F#-idioms, or possibly because there are some language-constructs that I have not yet been exposed to.</p>
  
  <pre><code>// Test data
  let numbers = {1.0..1000.0}
  let baseTime = DateTime.Now
  let contiguousTimeStamps = seq { for n in numbers -&gt;baseTime.AddMinutes(n)}
  
  let dataWithOccationalHoles = Seq.zip contiguousTimeStamps numbers |&gt; Seq.filter (fun (dateTime, num) -&gt; num % 77.0 &lt;&gt; 0.0) // Has a gap in the data every 77 items
  
  let timeBetweenContiguousValues = (new TimeSpan(0,1,0))
  
  dataWithOccationalHoles |&gt; groupContiguousDataPoints timeBetweenContiguousValues |&gt; Seq.iteri (fun i sequence -&gt; printfn "Group %d has %d data-points: Head: %f" i (Seq.length sequence) (snd(Seq.hd sequence)))
  </code></pre>