Lets talk about Language.Ext specifically and if you're interested in the languageExt tutorial go to The languageExt Tutorial

If you want to know a little about functional programming ideas generally, checkout 

People who know Functional programming tend to throw around a lot of buzzwords like "Composing of functions", "Declarative code syntax", "Monads", "Functors", "Pure functions", "Immutability". The former I talked about in Pure functions, and the later, I talked about in Being a bit more functional

So lets talk about monads.

Monads are design patterns designed to prevent boilerplate code.

Enumerable<T> is a monad that removes the foreach boilerplate code. Monads can also eliminate the need to if..else imperative conditionals in your code but still achieve them. Monads can use Bind() to achieve this. I'll talk about how that looks like a bit later.

So what are monads? Well, they are just classes or objects really. Usually, they are likened to C++ STL containers in as much as they need to support a specific interface and have features that make working with any monads predictable. For now, you can assume a monad is just a type like a stack or a list that have the following distinct features:

Monads are objects that:

  1. Have a Select() extension method extracts an item from the Monad and allows a function to run for each item in the monad. That function happens to be called a mapping function (a value producing function). You can safely assume that a monad is a container of items or just one item and you need to access the elements of a container. A mapping function allows you to not only access the items but act on each item or transform it someway). This is what a user-provided mapping function will do for a monad to which its used on.  By applying a function that runs against each item in the monad and turns in into something else.
  2. Have a SelectMany()-like extension method (its called Bind() )  which extracts an item from the Monad that allows a monad producing a function to be run for each item in the monad. That function happens to be called a binding function (a monad producing function)
    1. This is not SelectMany() and described in Understanding how the Linq query syntax works but similar as it doesn't actually call any project() and its called Bind()!
  3. Have the following functions defined for the type:
  4.     Sum                 // For Option<int> it's the wrapped value.
        Count               // For Option<T> is always 1 for Some and 0 for None.  
        Bind                // Part of the definition of anything monadic - SelectMany in LINQ
        Exists              // Any in LINQ - true if any element fits a predicate
        Filter              // Where in LINQ
        Fold                // Aggregate in LINQ
        ForAll              // All in LINQ - true if all element(s) fits a predicate
        Iter                // Passes the wrapped value(s) to an Action delegate
        Map                 // Part of the definition of any 'functor'.  Select in LINQ
        Lift / LiftUnsafe   // Different meaning to Haskell, this returns the wrapped value.  Dangerous, should be used sparingly.
        Select
        SeletMany
        Where

It must just be quickly be said, that the Select() function on a Monad or on an IEnumerable<T> fulfils the same functionality as the foreach operator and as such removes the need to use it and thus removes that particular piece of boilerplate code. The IF conditional will be replaced by the Bind() operation on Monads but I'm getting ahead of myself.

This enables Linq syntax (which is usable only by types that have a Select() and SellectMany()) to work on monads (Monads do have a SelectMany() and a Bind() also).

To understand how Select() and SelectMany() works checkout Understanding how the Linq query syntax works. There i describe how IEnumerable has Select() and SelectMany(). 

This suggests that you can enable any types (much as monads) to be used in LINQ expressions if they have a Select() and a SelectMany() like I've done here

But while your types can be used in LINQ expressions these types are not yet Monads until they also have Return() and Bind() extension methods (which are also similar to their Select and SelectMany counterparts):

  1. Map() extension method, like Select extension method, extracts the item and runs a provided mapping function on it,  however, it will put the transformation into a monad
  2. Bind() extension method, like the SelectMany extension method, extracts the item and passes it to a binding function(monad producing function) without the project() function that SelectMany() performs. The transfomation function needs to return a monad ie put the transformation into a monad.

This is how Linq is used, just it with an IEnumerable<T> to deal with a Monad called an Option<T> in language.ext:

using static LanguageExt.Prelude;
 
   Option<string> optionA = Some("Hello, ");
   Option optionB = Some("World");
   Option optionNone = None;
 
   var result1 = from x in optionA
                 from y in optionB
                 select x + y;
 
   var result2 = from x in optionA
                 from y in optionB
                 from z in optionNone
                 select x + y + z;

So this code actually uses LINQ to get inside a monad, like for-each gets an item from within an enumerable.

In many cases, this (the value extracted from the IEnumerable or Monad) is either their or it isn't - obviously if its there, then you can use it - if its not, nothing that would have used it ever uses it (more on this idea later)...

 So this is how it works (monads generally) when using Linq syntax specifically (you'll see this is exactly like how you used it with an IEnumerable):

from a in ma

This is saying “Get the value, a out of the monad ma”. For IEnumerable that means get the values from the say List<T>,

for Option<T> it means get the value if it's not in a None state. (More on what this means later) - This is validation.

As before, the following is saying “Get the value a out of monad ma, and then if we have a value get the value b out of monad mb”. So for IEnumerable if ma is an empty collection then the second from won't run - see more about the validation in the implementation of Map and Bind() 

For Option<T> if ma is a None then the second from won't run.

x = from a in ma
      from b in mb
      select a + b;

select in monad land, specifically above, means automatically put this value back into a new monad x

Select()and SelectMany() are extension methods that loop through the items and then put them back into the list.

So implementing a Select and a SelectMany makes it possible to use :

from a in ma

where there exists an extension method for ma called Select() as described in Understanding Select and SelectMany Implementation which is useful to look at if you dont quite understand the following conversation...

So this states that a Select invocation on an IEnumerable will run the map function on each item on the enumerable and place it back as an enumerable. In this way, map() says it will run a function on each item on the enumerable, a map function. Map() is run on every value in the enumerable

Also, a SelectMany invocation on an IEnumerable will run the bind function(which results in a IEnumerable) on each item in the list. Each item in the resulting list run against a project() function. See tutorial 01

So a bind function(for an IEnumerable) is run to transform the extracted item, and then derived from the input as each item in the IEnumerable, each item in the subsequnt list is evaluated by a project function which used the top level looping item in the enumerable that was used to produce the secondary list.

Select allows this to work:

from a in ma
    select a;

SelectMany allows this to work:

from a in ma
    from b in mb
    select a + b;

Ok, will all that being said and done, we've established that a Select() and SelectMany() extension method allows both IEnumerable and Monads to be used under the Linq syntax query. We've also established that Select() eliminates the need to use foreach(). We've also said that IEnumerable and Monads can initially be see as similar container objects.

By the way, if a type has a Select/map function, its called a functor type. It also has a Bind() is called a monad function. We've not talked about bind yet, which is discussed in Part 3.

If a type has Select() and SelectMany() its a monadic type. More specifically, if its got a Bind() along with the Select() its monadic

 So let's talk about two of Languages Ext's types then, which happen to be Monads:

Either<T1, T2> container basically says I can only contain a value of type T1 or T2 but not both. Option<T> says I optionally have a value of type T in me. Now here comes the crux of what I've been explaining all this time.

To obtain/extract/access the contents of the Either<T1, T2> or Option<T> to see what it really is, you need to either call :

  1. Map() - which is the equivalent of IEnumerable<T>'s Select() and by extension use the Linq syntax,
  2. Match() - which allows you to define a function that deals with each possible outcome of the extracted value
    1. So this means you'll be able to have a function that works with T1 if its there or T2 if its there
    2. So this means that you'll be able to define a function that access the T in Option<T> if its there or define a function that deals with it not being there.
  3. Bind()  - This is the magic function that not only accesses the items in the Monad but also removes the need to have if()..else{} imperatives conditionals in your code, which again are a source of common programming problems - another boilerplater removal triumph!.
    1. To see actually how bind works read the next part, Bind behind the scenes, which really demystifies the magic that Bind seems to hide. Bind is also the piece that allows you to to conditional if like code without actually doing imperative if() else{} c# code...

At this point, its worth seeing a few examples from languageExts site: https://github.com/louthy/language-ext#c-functional-programming-language-extensions to get an idea of how what I've been talking about fits into C#.

I'll look to make further examples here at a later stage. For now, lets look at Bind() goto Bind behind the scenes