public static StateT <S, M, B> Bind <B>(StateT <S, M, A> monad, Func <A, StateT <S, M, B> > f) { GetInnerMonadMethods(); // Console.WriteLine("StateT.Bind"); Func <object, M> binder = (o) => { // Console.WriteLine("StateT.Bind.binder"); // Console.WriteLine(o.GetType().Name); // Console.WriteLine(typeof(Tuple<A,S>).Name); var t = (Tuple <A, S>)o; return(StateT <S, M, B> .Run(f(t.Item1), t.Item2)); }; // Console.WriteLine("S = {0}", typeof(S).Name); // var typeM = typeof(M); // Console.WriteLine("M = {0}", typeM.Name); // Console.WriteLine("A = {0}", typeof(A).Name); // Console.WriteLine(String.Join(", ", typeM.GetMethods(BindingFlags.Static | BindingFlags.Public).Select(mi => mi.Name))); // Console.WriteLine(bindM?.ToString() ?? "Unable to find Bind on M"); return(new StateT <S, M, B>((s) => { // Console.WriteLine("StateT.Bind.invoker"); var tup = StateT <S, M, A> .Run(monad, s); // Console.WriteLine(tup.GetType()); // Console.WriteLine(binder.GetType()); return bindM(tup, binder); })); }
public static M Run(StateT <S, M, A> monad, S state) { return(monad.Value.Invoke(state)); }