public void ReaderWriterStateTest1() { var world = RWS.Return <Env, string, App, int>(0); var rws = (from _ in world from app in RWS.Get <Env, string, App>() from env in RWS.Ask <Env, string, App>() from x in Value(app.UsersLoggedIn, "Users logged in: " + app.UsersLoggedIn) from y in Value(100, "System folder: " + env.SystemFolder) from s in RWS.Put <Env, string, App>(new App { UsersLoggedIn = 35 }) from t in RWS.Tell <Env, string, App>("Process complete") select x *y) .Memo(new Env(), new App()); var res = rws(); Assert.True(res.Value == 3400); Assert.True(res.State.UsersLoggedIn == 35); Assert.True(res.Output.Count() == 3); Assert.True(res.Output.First() == "Users logged in: 34"); Assert.True(res.Output.Skip(1).First() == "System folder: C:/Temp"); Assert.True(res.Output.Skip(2).First() == "Process complete"); }
// RWSMonad usage example 1 : Realize the contents performed in each Example 1 of WriterMonad, ReaderMonad, and StateMonad with one RWSMonad public void Example1() { var checkCount = from currentState in RWS.Get <DateTime, string, SampleState>() from date in RWS.Ask <DateTime, string, SampleState>() from _ in RWS.Tell <DateTime, string, SampleState>(date.ToString("yyyy/MM/dd HH:mm:ss")) from greeting in RWS.Tell <DateTime, string, SampleState, string>(currentState.Count == 0 ? "Nice to meet you" : "Hello", string.Format("currentState.Count = {0}", currentState.Count)) from comment in RWS.Return <DateTime, string, SampleState, string>(greeting + ", Monad world!") from __ in RWS.Tell <DateTime, string, SampleState>("Add count") from putAddCount in RWS.Put <DateTime, string, SampleState>(new SampleState(currentState.Count + 1)) select comment; var result1State = checkCount.Execute( new DateTime(2000, 1, 1, 10, 20, 30), defaultState, value => Debug.Log(value), outPut => { foreach (var log in outPut) { Debug.Log(string.Format("Log[{0}]", log)); } }); var result2State = checkCount.Execute( DateTime.UtcNow, result1State, value => Debug.Log(value), outPut => { foreach (var log in outPut) { Debug.Log(string.Format("Log[{0}]", log)); } }); Debug.Log(string.Format("It has been called {0} times", result2State.Count)); }
public static RWS <MonoidW, R, W, S, bool> Exists <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> self, Func <A, bool> pred) where MonoidW : struct, Monoid <W> => (env, state) => { var res = self(env, state); return(res.IsFaulted ? RWSResult <MonoidW, R, W, S, bool> .New(res.Output, state, false) : RWSResult <MonoidW, R, W, S, bool> .New(res.Output, res.State, pred(res.Value))); };
public static RWS <MonoidW, R, W, S, R> Fold <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> self, Func <R, A, R> f) where MonoidW : struct, Monoid <W> => (env, state) => { var res = self(env, state); return(res.IsFaulted ? RWSResult <MonoidW, R, W, S, R> .New(res.Output, state, res.Error) : RWSResult <MonoidW, R, W, S, R> .New(res.Output, res.State, f(env, res.Value))); };
public static RWS <MonoidW, R, W, S, int> Count <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> self) where MonoidW : struct, Monoid <W> => (env, state) => { var res = self(env, state); return(res.IsFaulted ? RWSResult <MonoidW, R, W, S, int> .New(res.Output, state, res.Error) : RWSResult <MonoidW, R, W, S, int> .New(res.Output, res.State, 1)); };
/// <summary> /// Impure iteration of the bound value in the structure /// </summary> /// <returns> /// Returns the original unmodified structure /// </returns> public static RWS <MonoidW, R, W, S, A> Do <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> ma, Action <A> f) where MonoidW : struct, Monoid <W> => (env, state) => { var r = ma(env, state); if (!r.IsFaulted) { f(r.Value); } return(r); };
public static Seq <A> ToSeq <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> self, R env, S state) where MonoidW : struct, Monoid <W> { IEnumerable <A> Yield() { var res = self(env, state); if (!res.IsFaulted) { yield return(res.Value); } } return(Seq(Yield())); }
/// <summary> /// Runs the RWS monad and memoizes the result in a TryOption monad. Use /// Match, IfSucc, IfNone, etc to extract. /// </summary> public static RWSResult <MonoidW, R, W, S, A> Run <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> self, R env, S state) where MonoidW : struct, Monoid <W> { if (self == null) { throw new ArgumentNullException(nameof(self)); } if (state == null) { throw new ArgumentNullException(nameof(state)); } try { return(self(env, state)); } catch (Exception e) { return(RWSResult <MonoidW, R, W, S, A> .New(state, Error.New(e))); } }
public static RWS <MonoidW, R, W, S, A> Strict <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> ma) where MonoidW : struct, Monoid <W> { Option <RWSResult <MonoidW, R, W, S, A> > cache = default; object sync = new object(); return((env, state) => { if (cache.IsSome) { return cache.Value; } lock (sync) { if (cache.IsSome) { return cache.Value; } cache = ma(env, state); return cache.Value; } }); }
public static RWS <MonoidW, R, W, S, Unit> Modify <MonoidW, R, W, S, A>(RWS <MonoidW, R, W, S, A> self, Func <S, S> f) where MonoidW : struct, Monoid <W> => (env, state) => RWSResult <MonoidW, R, W, S, Unit> .New(default(MonoidW).Empty(), f(state), unit);
public static RWS <MonoidW, R, W, S, Seq <A> > AsEnumerable <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> self) where MonoidW : struct, Monoid <W> => ToSeq(self);
public static RWS <MonoidW, R, W, S, Seq <A> > ToSeq <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> self) where MonoidW : struct, Monoid <W> => self.Map(x => x.Cons());
public static RWS <MonoidW, R, W, S, int> Sum <MonoidW, R, W, S>(this RWS <MonoidW, R, W, S, int> self) where MonoidW : struct, Monoid <W> => self;
public override string ToString() { return($"{Name.PadRight(8, ' ')}{Rating.ToString("0.00").PadLeft(6, ' ')}{RWS.ToString("0.00").PadLeft(7, ' ')}{KD.ToString("0.00").PadLeft(6, ' ')}{ADR.ToString("0.0").PadLeft(7, ' ')}"); }
public MB Bind <MONADB, MB, B>(RWS <MonoidW, R, W, S, A> ma, Func <A, MB> f) where MONADB : struct, Monad <(R Env, S State), RWSState <W, S>, MB, B> =>
public static RWS <Env, string, App, int> Value(int val, string log) { return((Env r, App s) => RWS.Tell <string, App, int>(val, log)); }
public static Seq <A> AsEnumerable <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> self, R env, S state) where MonoidW : struct, Monoid <W> => ToSeq(self, env, state);
public static RWS <MonoidW, R, W, S, bool> ForAll <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> self, Func <A, bool> pred) where MonoidW : struct, Monoid <W> => Exists(self, pred);
public static RWS <MonoidW, R, W, S, B> Map <MonoidW, R, W, S, A, B>(this RWS <MonoidW, R, W, S, A> self, Func <A, B> project) where MonoidW : struct, Monoid <W> => self.Select(project);
public static RWS <MonoidW, R, W, S, A> Flatten <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, RWS <MonoidW, R, W, S, A> > ma) where MonoidW : struct, Monoid <W> => ma.Bind(identity);
public RWS <MonoidW, R, W, S, A> Apply(Func <A, A, A> f, RWS <MonoidW, R, W, S, A> fa, RWS <MonoidW, R, W, S, A> fb) => from a in fa from b in fb select f(a, b);
public static RWS <MonoidW, R, W, S, A> Pass <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, (A, Func <W, W>)> self)
/// <summary> /// Runs the RWS monad and memoizes the result in a TryOption monad. Use /// Match, IfSucc, IfNone, etc to extract. /// </summary> public static (TryOption <A> Value, W Output, S State) Run <MonoidW, R, W, S, A>(this RWS <MonoidW, R, W, S, A> self, R env, S state)
this RWS <MonoidW, R, W, S, A> self, R env, S state)