private static StateMonad <TState, Tree <Tuple <TState, TContents> > > MakeMonad(Tree <TContents> t, Func <StateMonad <TState, TState> > updater) { if (t is Leaf <TContents> ) { var lf = (t as Leaf <TContents>); return(updater() .Bind(n => StateMonad <TState, Tree <Tuple <TState, TContents> > > .Return(new Leaf <Tuple <TState, TContents> >(Tuple.Create(n, lf.Contents))))); } if (t is Branch <TContents> ) { var br = (t as Branch <TContents>); var oldleft = br.Left; var oldright = br.Right; return(MakeMonad(oldleft, _leftUpdater) .Bind(newleft => MakeMonad(oldright, _rightUpdater) .Bind(newright => StateMonad <TState, Tree <Tuple <TState, TContents> > > .Return(new Branch <Tuple <TState, TContents> >(newleft, newright))))); } throw new Exception("MakeMonad/MLabel: impossible Tree subtype"); }
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)))))); }
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"); }
private static StateMonad <TState, IEnumerable <StateContentPair <TState, TContent> > > CreateStateMonadRecursively <TState, TContent>(IEnumerable <TContent> list, StateMonad <TState, TState> updateMonad) { return(CreateStateMonadRecursively(list.ToList(), updateMonad, StateMonad.Return <TState, IEnumerable <StateContentPair <TState, TContent> > >(new List <StateContentPair <TState, TContent> >()))); }