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(nameof(bind)); } if (project == null) { throw new ArgumentNullException(nameof(project)); } return(() => { var resT = self.Valid()(); 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).Valid()(env); if (resU.IsBottom) { return ReaderResult.Bottom <V>(); } return ReaderResult.Return(project(resT.Value, resU.Value)); }, resT.Output); }); }
internal static Reader <Env, T> Valid <Env, T>(this Reader <Env, T> self) => self ?? (_ => ReaderResult.Bottom <T>());
private static ReaderResult <T> Bottom <T>() => ReaderResult.Bottom <T>();