Skip to content

Instantly share code, notes, and snippets.

@lulu-berlin
Last active October 13, 2015 20:40
Show Gist options
  • Save lulu-berlin/9998fdc03d9708eaf2b7 to your computer and use it in GitHub Desktop.
Save lulu-berlin/9998fdc03d9708eaf2b7 to your computer and use it in GitHub Desktop.
F# unfold without tuples
// Seq.unfold (https://msdn.microsoft.com/en-us/library/ee340363.aspx)
// works with a generator function that gets a state and returns
// Some (element, state) to generate another iterator, or
// None to stop the iteration.
// The problem is that tuples are allocated every single iteration.
//
// The solution below uses instead a generator function that gets
// a state and an iterator function. The iterator function can be called
// to yield a new element and set a new state for the next iterator. If the
// generator function returns a unit, i.e. (), the iteration stops.
//
// See example at the end.
let unfoldf<'T, 'State> (f: 'State -> ('T -> 'State -> unit) -> unit)
(state: 'State) =
let mutable _state = state
let mutable _element = None
let iterFunc (e: 'T) (s: 'State) =
_element <- Some e
_state <- s
f _state iterFunc
seq {
while _element.IsSome do
yield _element.Value
_element <- None
f _state iterFunc
}
// Example:
// Start with 0 as the initial state and yield its string representation,
// incrementing the state until it reaches 100.
let iter =
unfoldf (fun state iter ->
if state < 100
then iter (sprintf "%d" state) (state + 1)
else () // this part can be omitted
) 0
for x in iter do printfn "%s" x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment