I have a general question and a more specific case question.

How does one combine different monads in general? Does some combination of the monad operators allow easy composition? Or does one have to write ad-hoc methods to combine each possible pair of monads?

As a specific example, I wrote a Maybe monad. How would one go about using an IEnumerable<IMaybe<T>> ? Apart from manually digging in to the Maybe monad within the LINQ extensions (such as: if(maybe.HasValue)... within select clauses), is there a "monadic" way of combining the two with their respective Bind etc. monad operations?

Otherwise, if I have to write specific combining methods, is something like this the right way to go about it?

    public static IEnumerable<B> SelectMany<A, B>(this IEnumerable<A> sequence, Func<A, IMaybe<B>> func)
    {
        return from item in sequence
               let result = func(item)
               where result.HasValue
               select result.Value;
    }


    public static IEnumerable<C> SelectMany<A, B, C>(this IEnumerable<A> sequence, Func<A, IMaybe<B>> func, Func<A, B, C> selector)
    {
        return from item in sequence
               let value = item
               let maybe = func(item)
               where maybe.HasValue
               select selector(value, maybe.Value);
    }
Edit
Report