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("bind"); } if (project == null) { throw new ArgumentNullException("project"); } return((S s) => { var resT = self(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)(); 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 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("bind"); } if (project == null) { throw new ArgumentNullException("project"); } return(() => { var resT = self(); 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)(state); if (resU.IsBottom) { return StateResult.Bottom <S, V>(state); } return StateResult.Return(resU.State, project(resT.Value, resU.Value)); }, resT.Output); }); }
public static Writer <W, V> SelectMany <W, T, U, V>( this Writer <W, T> self, Func <T, Writer <W, U> > bind, Func <T, U, V> project ) { if (bind == null) { throw new ArgumentNullException("bind"); } if (project == null) { throw new ArgumentNullException("project"); } return(() => { var resT = self(); if (resT.IsBottom) { return WriterResult.Bottom <W, V>(resT.Output); } var resU = bind(resT.Value).Invoke(); if (resT.IsBottom) { return WriterResult.Bottom <W, V>(resU.Output); } var resV = project(resT.Value, resU.Value); return WriterResult.Return(resV, resT.Output.Concat(resU.Output)); }); }
public static Writer <Out, Reader <E, V> > SelectMany <Out, E, T, U, V>( this Writer <Out, T> self, Func <T, Reader <E, U> > bind, Func <T, U, V> project ) { if (bind == null) { throw new ArgumentNullException("bind"); } if (project == null) { throw new ArgumentNullException("project"); } return(() => { var resT = self(); if (resT.IsBottom) { return WriterResult.Bottom <Out, Reader <E, V> >(resT.Output); } return WriterResult.Return <Out, Reader <E, V> >(env => { var resU = bind(resT.Value)(env); if (resU.IsBottom) { return ReaderResult.Bottom <V>(); } return ReaderResult.Return(project(resT.Value, resU.Value)); }, resT.Output); }); }
public static Reader <E, Writer <Out, V> > SelectMany <E, Out, T, U, V>( this Reader <E, 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((E env) => { var resT = self(env); if (resT.IsBottom) { return Bottom <Writer <Out, V> >(); } return Return <Writer <Out, V> >(() => { var resU = bind(resT.Value)(); if (resU.IsBottom) { return WriterResult.Bottom <Out, V>(resU.Output); } return WriterResult.Return(project(resT.Value, resU.Value), resU.Output); }); }); }
public static Writer <W, T> Where <W, T>(this Writer <W, T> self, Func <T, bool> pred) { return(() => { var res = self(); return pred(res.Value) ? WriterResult.Return(res.Value, res.Output) : WriterResult.Bottom <W, T>(res.Output); }); }
public static Writer <Out, Unit> Iter <Out, T>(this Writer <Out, T> self, Action <T> action) { return(() => { var res = self(); if (!res.IsBottom) { action(res.Value); } return WriterResult.Return(unit, res.Output); }); }
private static WriterResult <W, Unit> bmap <W, T>(WriterResult <W, T> r, Action <T> f) { if (r.IsBottom) { return(WriterResult.Bottom <W, Unit>(r.Output)); } else { f(r.Value); return(WriterResult.Return <W, Unit>(unit, r.Output)); } }
public static Writer <Out, V> FoldT <Out, T, V>(this Writer <Out, Writer <Out, T> > self, V state, Func <V, T, V> fold) { return(() => { var inner = self(); if (inner.IsBottom) { return WriterResult.Bottom <Out, V>(inner.Output); } var res = inner.Value.Fold(state, fold)(); return WriterResult.Return <Out, V>(res.Value, inner.Output.Concat(res.Output)); }); }
public static Writer <Out, R> Bind <Out, T, R>(this Writer <Out, T> self, Func <T, Writer <Out, R> > binder) { return(() => { var t = self(); if (t.IsBottom) { return WriterResult.Bottom <Out, R>(t.Output); } var u = binder(t.Value)(); return WriterResult.Return(u.Value, t.Output.Concat(u.Output)); }); }
public static Writer <Out, State <S, V> > FoldT <Out, S, T, V>(this Writer <Out, State <S, T> > self, V state, Func <V, T, V> fold) { return(() => { var inner = self(); if (inner.IsBottom) { return WriterResult.Bottom <Out, State <S, V> >(inner.Output); } return WriterResult.Return <Out, State <S, V> >(s => inner.Value.Fold(state, fold)(s), inner.Output ); }); }
public static Writer <W, U> Select <W, T, U>(this Writer <W, T> self, Func <T, U> select) { if (select == null) { throw new ArgumentNullException("select"); } return(() => { var resT = self(); if (resT.IsBottom) { return WriterResult.Bottom <W, U>(resT.Output); } var resU = select(resT.Value); return WriterResult.Return(resU, resT.Output); }); }
public static Writer <Out, T> LiftUnsafeT <Env, Out, T>(this Reader <Env, Writer <Out, T> > self, Env env) where T : class { return(() => { var inner = self(env); if (inner.IsBottom) { return WriterResult.Bottom <Out, T>(); } var res = inner.Value(); if (res.IsBottom) { return WriterResult.Bottom <Out, T>(); } return WriterResult.Return(res.Value, res.Output); }); }
private static WriterResult <W, R> bmap <W, T, R>(WriterResult <W, T> r, Func <T, R> f) => r.IsBottom ? WriterResult.Bottom <W, R>(r.Output) : WriterResult.Return(f(r.Value), r.Output);