예제 #1
0
 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);
         });
     });
 }
예제 #2
0
 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);
     });
 }
예제 #3
0
        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));
            });
        }
예제 #4
0
 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);
     });
 }
예제 #5
0
 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);
         });
     });
 }
예제 #6
0
 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);
     });
 }
예제 #7
0
 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);
     });
 }
예제 #8
0
 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));
     }
 }
예제 #9
0
 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));
     });
 }
예제 #10
0
 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));
     });
 }
예제 #11
0
        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
                                                                );
            });
        }
예제 #12
0
 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);
     });
 }
예제 #13
0
 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);
     });
 }
예제 #14
0
 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);