3 people like it.
Like the snippet!
Splitting a sequence based on separator condition
Whilst working on a google API wrapper, I came across the need to separate a sequence into subsequences based on a separator condition. This also led to a requirement for versions of takeWhile and skipWhile which also include the element which first breaks the condition predicate.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:

let notEmpty s = not (Seq.isEmpty s)
// inclusive version of takeWhile  includes the element which broke the condition
let takeWhileInc cond s =
seq {
yield! s > Seq.takeWhile cond
let r = s > Seq.skipWhile cond
if notEmpty r then yield r > Seq.head
}
// inclusive version of skipWhile  also skips the first element which broke the condition
let skipWhileInc cond s =
let r = s > Seq.skipWhile cond
if notEmpty r then (r > Seq.skip 1) else r
// split a large sequence into a sequence of sequences, determined by a splitter condition
let rec splitSubSequences cond s =
seq {
if not (s > Seq.isEmpty) then
yield (s > takeWhileInc cond)
yield! (s > skipWhileInc cond > splitSubSequences cond)
}

val notEmpty : s:seq<'a> > bool
Full name: Script.notEmpty
val s : seq<'a>
val not : value:bool > bool
Full name: Microsoft.FSharp.Core.Operators.not
module Seq
from Microsoft.FSharp.Collections
val isEmpty : source:seq<'T> > bool
Full name: Microsoft.FSharp.Collections.Seq.isEmpty
val takeWhileInc : cond:('a > bool) > s:seq<'a> > seq<'a>
Full name: Script.takeWhileInc
val cond : ('a > bool)
Multiple items
val seq : sequence:seq<'T> > seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq

type seq<'T> = System.Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val takeWhile : predicate:('T > bool) > source:seq<'T> > seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.takeWhile
val r : seq<'a>
val skipWhile : predicate:('T > bool) > source:seq<'T> > seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.skipWhile
val head : source:seq<'T> > 'T
Full name: Microsoft.FSharp.Collections.Seq.head
val skipWhileInc : cond:('a > bool) > s:seq<'a> > seq<'a>
Full name: Script.skipWhileInc
val skip : count:int > source:seq<'T> > seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.skip
val splitSubSequences : cond:('a > bool) > s:seq<'a> > seq<seq<'a>>
Full name: Script.splitSubSequences
More information