Welcome to MSDN Blogs Sign in | Join | Help

jaredpar's WebLog

Code, rants and ramblings of a programmer.

Syndication

News

Now Reading

Expert F#

What's a better book to read when learning F#?

Essential WPF

Thus far the best book I've read on WPF. Gets right down to working with WPF and the goals/history.

Purely Functional Data Structures

Reading this book makes me feel like I'm back in college. It will really get your mind going and is best read with a whiteboard handy.

Blog Roll

Eric Lippert
Dustin Campbell
Jon Skeet
Coding Horror
Brian McNamara
Hub FS
Full List

Unfold

F# has a handy method called Unfold.  Think of it as the logical opposite of an Aggregate function.  Aggregates take a sequence of elements and convert them to a single element.  An unfold method will take a single element and turn it into a (potentially infinite) sequence of elements. 

The API is straight forward.  It takes two parameters

  1. A seed/start value
  2. A function which takes in a seed value and returns either an Empty option to indicate the end of a sequence or a value of Type tuple with two arguments.  The first is the next element in the sequence and the second is the next seed value passed into the function.

This is a very powerful function which allows you to quickly build all sorts of interesting functions.  Lets look at a potential implementation of Enumerable.Range as an unfold expression.

public static IEnumerable<int> Range(int start, int count)
{
    return Enumerable.Unfold(
        start,
        x => x - start < count
            ? Option.Create(Tuple.Create(x, x + 1))
            : Option.Empty);
}

Not as efficient as the framework version of Range but a good mental exercise to get your head around using Unfold.  Implementing this method in C# is fairly straight forward.

public static IEnumerable<TResult> Unfold<TSource, TResult>(
    TSource state, 
    Func<TSource, Option<Tuple<TResult, TSource>>> func)
{
    if (func == null)
    {
        throw new ArgumentNullException("func");
    }

    return UnfoldHelper(state, func);
}

private static IEnumerable<TResult> UnfoldHelper<TSource, TResult>(
    TSource state, 
    Func<TSource, Option<Tuple<TResult, TSource>>> func)
{
    do
    {
        var result = func(state);
        if (!result.HasValue)
        {
            break;
        }

        yield return result.Value.First;
        state = result.Value.Second;
    } while (true);
}

Published Tuesday, October 07, 2008 8:00 AM by Jared Parsons

Filed under: , , ,

Comments

# Unfold : EasyCoded @ Tuesday, October 07, 2008 8:13 AM

PingBack from http://www.easycoded.com/unfold/

Unfold : EasyCoded

# re: Unfold @ Tuesday, October 07, 2008 4:31 PM

Jared,

I've covered this a bit in my series here on unfolding lists and go a little deeper here (http://codebetter.com/blogs/matthew.podwysocki/archive/2008/06/12/functional-c-unfolding-lists.aspx).  It's part of my functional C# library on MSDN Code Gallery (http://code.msdn.microsoft.com/FunctionalCSharp)

Matt

Matthew Podwysocki

# re: Unfold @ Tuesday, October 07, 2008 4:40 PM

@Matthew

I'll have to check out your library.  I keep a similar library on MSDN code gallery for many of my functional and threading utilities.  

http://code.msdn.microsoft.com/RantPack

Jared Parsons

New Comments to this post are disabled
Page view tracker