Reading a Previous SO Question I was confused to find Eric Lippert saying that an interface cannot be defined in C# for all Monads, using an implementation as below:
typeInterface Monad<MonadType<A>> { static MonadType<A> Return(A a); static MonadType<B> Bind<B>(MonadType<A> x, Func<A, MonadType<B>> f); } My problem is all the problems listed in the question seem to have easy solutions:
- no "higher kinded types" => use parent interfaces
- no static method in interface. => why use static?! just use instance methods
Monad is a pattern allowing chaining of operations on wrapped types it seems easy to define a C# interface for all Monads allowing us to write a generic class for all monads Where's the problem?
using System; using System.Linq; public class Program { public static void Main() {//it works, where's the problem? new SequenceMonad<int>(5) .Bind(x => new SequenceMonad<float>(x + 7F)) .Bind(x => new SequenceMonad<double>(x + 5D)) ; } interface IMonad<T>{ IMonad<T> Wrap(T a); IMonad<U> Bind<U>(Func<T, IMonad<U>> map); T UnWrap();//if we can wrap we should be able to unwrap } class GenericClassForAllMonads<T> {//example writing logic for all monads IMonad<U> DoStuff<U>(IMonad<T> input, Func<T, IMonad<U>> map) { return map(input.UnWrap()); } } class SequenceMonad<T> : IMonad<T> where T:new() {//specific monad implementation readonly T[] items;//immutable public SequenceMonad(T a) { Console.WriteLine("wrapped:"+a); items = new[] { a }; } public IMonad<B> Bind<B>(Func<T, IMonad<B>> map) { return map(UnWrap()); } public T UnWrap() { return items == null? default(T) : items.FirstOrDefault(); } public IMonad<T> Wrap(T a) { Console.WriteLine("wrapped:"+a); return new SequenceMonad<T>(a); } } }
sequal to{1, 2, 3}, thens.Bind(x => Repeat(x, 2))is the sequence{1,1,2,2,3,3}, for example. Your implementation does not have any concatenation logic in it.