Monads, part twelve

Holy goodness, this series got a lot longer than I expected. I was hoping to get to some actual category theory, but let’s just talk a bit about LINQ and then wrap up. Maybe I’ll do a series on the basics of category theory in the future.

I’ve said several times that SelectMany is the bind operation on the sequence monad, but of course there are several overloads of the SelectMany extension method of IEnumerable<T>. The one that is bind is as we previously discussed:  (Error checking removed for clarity.)

public static IEnumerable<R> SelectMany<A, R>(
  this IEnumerable<A> items, 
  Func<A, IEnumerable<R>> function)
{
  foreach(A outer in items)
    foreach(R inner in function(outer))
      yield return inner;
}

Now you might think that when you say

from outer in items
from inner in function(outer)
select inner

this translates directly into a call to

items.SelectMany(outer=>function(outer))

This is not what actually happens.

Continue reading