Basically, it's a bit of glue that joins two functions together. I decided to write one for myself in C# to see what it would look like without any syntactic sugar that other languages might provide:
public static class Binding {
public static Func<TInput, TOutput> Bind<TInput, TIntermediate, TOutput>(Func<TInput, TIntermediate> left, Func<TIntermediate, TOutput> right) {
return arg => right(left(arg));
}
}
It's designed so that the output of
left
"flows" into the input of right
. The output of the rightmost function is returned to the caller as the result of the expression. Here are two functionally equivalent examples (one written normally, and the other with monads):Func<string, IEnumerable<char>> js = s => s.Select(c => c - '0').Where(i => i % 2 == 0).Select(i => (char)(i + 'a')).Select(c => Char.ToUpper(c));
Func<string, IEnumerable<char>> ks = Binding.Bind<IEnumerable<char>, IEnumerable<int>, IEnumerable<char>>(
k1 => k1.Select(c => c - '0'),
Binding.Bind, IEnumerable<int>, IEnumerable<char>>(
k2 => k2.Where(i => i % 2 == 0),
Binding.Bind<IEnumerable<int>, IEnumerable<char>, IEnumerable<char>>(
k3 => k3.Select(i => (char)(i + 'a')),
k4 => k4.Select(c => Char.ToUpper(c)))));
Check that they work as expected:
Debug.Assert(ks("0123456789").SequenceEqual(new char[] {'A','C','E','G','I'}));
1 comment:
This is not a monad, it's just function composition, and the example is a 'map' and a 'filter'. Take a look at this article for a good explanation of monads in C#: http://blogs.msdn.com/b/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx
Post a Comment