Just wanted to share a couple little functions that I was playing with since it made my code terse and readable. At first I needed a way to fold a function until a predicate. This way I could stop and didn’t have to continue through the whole list. Then I needed to be able to do the same kind of thing but choosing all elements up until a predicate.

Folding

First, folding. I wanted to be able to get all the characters up until white space. For example:

  
let (++) a b = a.ToString() + b.ToString()

let upToSpaces str = foldTill Char.IsWhiteSpace (++) "" str  

Which led me to write the following fold function. Granted it’s not lazy evaluated, but for me that was OK.

  
let foldTill check predicate seed list=  
 let rec foldTill' acc = function  
 | [] -\> acc  
 | (h::t) -\> match check h with  
 | false -\> foldTill' (predicate acc h) t  
 | true -\> acc  
 foldTill' seed list  

Running this gives

  
\> upToSpaces "abcdef gh";;  
val it : string = "abcdef"  

Here’s a more general way of doing it for sequences. Granted it has mutable state, but its hidden in the function and never leaks. This is very similar to how fold is implemented in F# core, I just added the extra check before it calls into the fold predicate

  
let foldTill check predicate seed (source:seq\<'a\>) =  
 let finished = ref false  
 use e = source.GetEnumerator()  
 let mutable state = seed  
 while e.MoveNext() && not !finished do  
 match check e.Current with  
 | false -\> state \<- predicate state e.Current  
 | true -\> finished := true  
 state  

Anyways, fun!