xonkvq
Last Updated: February 25, 2016
·
363
· vincpa
7a1054e17f3c41c66b1b28d4d6b09379

Using LINQ without collections or sequences

I had never considered using LINQ for anything other than collections or sequences of data until I came across a blog post by Wes Dyer. The compiler is obviously converting the query syntax (from x in y) to use SelectMany, but it's smart enough to get our custom version of SelectMany().

How else can we use LINQ in this way, more creatively ?

public class Identity<T>
{
    public T Value { get; private set; }
    public Identity(T value) { this.Value = value; }

    public static implicit operator Identity<T>(T value) {
        return new Identity<T>(value);
    }
}

static class MonadicExtensions
{   
    // "Hijack" LINQ query expressions so that IEnumerable<T> isn't a requirement.
    public static Identity<Z> SelectMany<T,R,Z>(
        this Identity<T> source,
        Func<T, Identity<R>> function,
        Func<T,R,Z> s) {

        T unwrapped = source.Value;

        Identity<R> result = function(unwrapped);

        return s(unwrapped, result.Value);
    }

    public static Identity<T> ToIdentity<T>(this T value) {
        return value;
    }
}

void Main()
{
    // Returns Identity<int>, not IEnumerable or IQueryable.
    var results = 
        from x in 5.ToIdentity()
        from y in 10.ToIdentity()
        select x + y;

    Console.WriteLine (results);
}

// Full credit goes to Wes Dyer http://blogs.msdn.com/b/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx

Say Thanks
Respond