Till functions
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!