public static StateMonad <TState, IEnumerable <StateContentPair <TState, TContent> > > CreateStateMonadFunctionally <TState, TContent>(IEnumerable <TContent> list, StateMonad <TState, TState> updateMonad) { var monad = list .Aggregate(StateMonad.Return <TState, IEnumerable <StateContentPair <TState, TContent> > >(new List <StateContentPair <TState, TContent> >()), (current, s) => current .Bind(x1 => updateMonad .Bind(x => StateMonad.Return <TState, IEnumerable <StateContentPair <TState, TContent> > >(new[] { StateContentPair.Create(x, s) })) .Bind(x2 => StateMonad.Return <TState, IEnumerable <StateContentPair <TState, TContent> > >(x1.Concat(x2))))); return(monad); }
private static StateMonad <TState, IEnumerable <StateContentPair <TState, TContent> > > CreateStateMonadRecursively <TState, TContent>(IReadOnlyCollection <TContent> list, StateMonad <TState, TState> updateMonad, StateMonad <TState, IEnumerable <StateContentPair <TState, TContent> > > result) { if (!list.Any()) { return(result); } return(CreateStateMonadRecursively(list.Skip(1).ToList(), updateMonad, result .Bind(res => updateMonad .Bind(state => StateMonad.Return <TState, IEnumerable <StateContentPair <TState, TContent> > >(new[] { StateContentPair.Create(state, list.First()) })) .Bind(nextItem => StateMonad.Return <TState, IEnumerable <StateContentPair <TState, TContent> > >(res.Concat(nextItem)))))); }
/** * Simple example of running a string through a calculation involving * destructive update modelled by a state monad. * * @param initial the starting string. * @return the result of running the string through the computation. */ public static String ToUpperCase(String initial) { var m = new StateMonad(); // do a <- lookup // mutate(a.toUpperCase) // lookup Computation c = m.Bind(m.Lookup(), new C(m)); return((String)m.Run(c, initial).Value()); }
private static StateMonad <TState, Tree <StateContentPair <TState, T> > > CreateLabeledTree <TState, T>(Tree <T> tree, StateMonad <TState, TState> updateMonad) { if (tree is Leaf <T> ) { var leaf = (tree as Leaf <T>); return(updateMonad.Bind(n => StateMonad.Return <TState, Tree <StateContentPair <TState, T> > >(Leaf.Create(StateContentPair.Create(n, leaf.Content))))); } if (tree is Branch <T> ) { var branch = (tree as Branch <T>); // recursion return(CreateLabeledTree(branch.Left, updateMonad) .Bind(newleft => CreateLabeledTree(branch.Right, updateMonad) .Bind(newright => StateMonad.Return <TState, Tree <StateContentPair <TState, T> > >(Branch.Create(newleft, newright))))); } throw new Exception("MakeMonad/MLabel: impossible tree subtype"); }