public static State <S, Writer <Out, V> > SelectMany <S, Out, T, U, V>( this State <S, T> self, Func <T, Writer <Out, U> > bind, Func <T, U, V> project ) { if (bind == null) { throw new ArgumentNullException(nameof(bind)); } if (project == null) { throw new ArgumentNullException(nameof(project)); } return((S s) => { var resT = self.Valid()(s); if (resT.IsBottom) { return StateResult.Bottom <S, Writer <Out, V> >(s); } return StateResult.Return <S, Writer <Out, V> >(resT.State, () => { var resU = bind(resT.Value).Valid()(); if (resU.IsBottom) { return new WriterResult <Out, V>(default(V), resU.Output, true); } return WriterResult.Return(project(resT.Value, resU.Value), resU.Output); }); }); }
public static Reader <E, State <S, V> > SelectMany <E, S, T, U, V>( this Reader <E, T> self, Func <T, State <S, U> > bind, Func <T, U, V> project ) { if (bind == null) { throw new ArgumentNullException(nameof(bind)); } if (project == null) { throw new ArgumentNullException(nameof(project)); } return((E env) => { var resT = self.Valid()(env); if (resT.IsBottom) { return Bottom <State <S, V> >(); } return Return <State <S, V> >(state => { var resU = bind(resT.Value).Valid()(state); if (resU.IsBottom) { return StateResult.Bottom <S, V>(state); } return StateResult.Return(resU.State, project(resT.Value, resU.Value)); }); }); }
public static Writer <Out, State <S, V> > SelectMany <Out, S, T, U, V>( this Writer <Out, T> self, Func <T, State <S, U> > bind, Func <T, U, V> project ) { if (bind == null) { throw new ArgumentNullException(nameof(bind)); } if (project == null) { throw new ArgumentNullException(nameof(project)); } return(() => { var resT = self.Valid()(); if (resT.IsBottom) { return WriterResult.Bottom <Out, State <S, V> >(resT.Output); } return WriterResult.Return <Out, State <S, V> >(state => { var resU = bind(resT.Value).Valid()(state); if (resU.IsBottom) { return StateResult.Bottom <S, V>(state); } return StateResult.Return(resU.State, project(resT.Value, resU.Value)); }, resT.Output); }); }
public static State <S, V> SelectMany <S, T, U, V>( this State <S, T> self, Func <T, State <S, U> > bind, Func <T, U, V> project ) { if (bind == null) { throw new ArgumentNullException(nameof(bind)); } if (project == null) { throw new ArgumentNullException(nameof(project)); } return((S state) => { var resT = self.Valid()(state); if (resT.IsBottom) { return StateResult.Bottom <S, V>(state); } var resU = bind(resT.Value).Valid()(resT.State); if (resU.IsBottom) { return StateResult.Bottom <S, V>(resT.State); } var resV = project(resT.Value, resU.Value); return StateResult.Return(resU.State, resV); }); }
public static State <S, Reader <E, V> > SelectMany <S, E, T, U, V>( this State <S, T> self, Func <T, Reader <E, U> > bind, Func <T, U, V> project ) { if (bind == null) { throw new ArgumentNullException(nameof(bind)); } if (project == null) { throw new ArgumentNullException(nameof(project)); } return((S s) => { var resT = self.Valid()(s); if (resT.IsBottom) { return StateResult.Bottom <S, Reader <E, V> >(s); } return StateResult.Return <S, Reader <E, V> >(resT.State, envInner => { var resU = bind(resT.Value).Valid()(envInner); if (resU.IsBottom) { return new ReaderResult <V>(default(V), true); } return ReaderResult.Return(project(resT.Value, resU.Value)); }); }); }
public static State <S, int> Count <S, T>(this State <S, T> self) => s => { var res = self.Valid()(s); return(res.IsBottom ? StateResult.Bottom <S, int>(s) : StateResult.Return(res.State, 1)); };
public static State <S, Writer <Out, V> > FoldT <S, Out, T, V>(this State <S, Writer <Out, T> > self, V state, Func <V, T, V> fold) { return((S s) => { var inner = self.Valid()(s); if (inner.IsBottom) { return StateResult.Bottom <S, Writer <Out, V> >(s); } return StateResult.Return(inner.State, inner.Value.Fold(state, fold)); }); }
static StateResult <S, Unit> bmap <S, T>(StateResult <S, T> r, Action <T> f) { if (r.IsBottom) { return(StateResult.Bottom <S, Unit>(r.State)); } else { f(r.Value); return(StateResult.Return(r.State, unit)); } }
public static State <S, R> Bind <S, T, R>(this State <S, T> self, Func <T, State <S, R> > binder) { return(state => { var resT = self.Valid()(state); if (resT.IsBottom) { return StateResult.Bottom <S, R>(state); } return binder(resT.Value).Valid()(resT.State); }); }
public static State <S, T> Where <S, T>(this State <S, T> self, Func <T, bool> pred) { return(state => { var res = self.Valid()(state); if (res.IsBottom) { return StateResult.Bottom <S, T>(state); } return pred(res.Value) ? StateResult.Return(res.State, res.Value) : StateResult.Bottom <S, T>(state); }); }
public static State <S, U> Select <S, T, U>(this State <S, T> self, Func <T, U> map) { if (map == null) { throw new ArgumentNullException(nameof(map)); } return((S state) => { var resT = self.Valid()(state); return resT.IsBottom ? StateResult.Bottom <S, U>(state) : StateResult.Return(resT.State, map(resT.Value)); }); }
public static State <S, T> Modify <S, T>(this State <S, T> self, Func <S, S> f) { if (f == null) { throw new ArgumentNullException(nameof(map)); } return((S state) => { var resT = self.Valid()(state); return resT.IsBottom ? StateResult.Bottom <S, T>(state) : StateResult.Return(f(resT.State), resT.Value); }); }
public static State <S, T> LiftUnsafeT <Env, S, T>(this Reader <Env, State <S, T> > self, Env env) where T : class { return(state => { var inner = self.Valid()(env); if (inner.IsBottom) { return StateResult.Bottom <S, T>(state); } var res = inner.Value(state); if (res.IsBottom) { return StateResult.Bottom <S, T>(state); } return StateResult.Return(res.State, res.Value); }); }
internal static State <S, T> Valid <S, T>(this State <S, T> self) => self ?? (s => StateResult.Bottom <S, T>(s));
static StateResult <S, R> bmap <S, T, R>(StateResult <S, T> r, Func <T, R> f) => r.IsBottom ? StateResult.Bottom <S, R>(r.State) : StateResult.Return(r.State, f(r.Value));