Skip to content

Commit af94d40

Browse files
committed
Add Done/Loop support directly to Monad
1 parent eb14f4c commit af94d40

3 files changed

Lines changed: 42 additions & 5 deletions

File tree

LanguageExt.Core/Traits/Monads/Monad/Monad.Module.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ public static MB bind<M, MB, A, B>(K<M, A> ma, Func<A, MB> f)
3333
where M : Monad<M> =>
3434
(MB)bind(ma, x => f(x));
3535

36+
/// <summary>
37+
/// Lift a Next.Done value into the monad
38+
/// </summary>
39+
[Pure]
40+
public static K<M, Next<A, B>> done<M, A, B>(B value)
41+
where M : Monad<M> =>
42+
M.Pure(Next.Done<A, B>(value));
43+
44+
/// <summary>
45+
/// Lift a Next.Done value into the monad
46+
/// </summary>
47+
[Pure]
48+
public static K<M, Next<A, B>> loop<M, A, B>(A value)
49+
where M : Monad<M> =>
50+
M.Pure(Next.Loop<A, B>(value));
51+
3652
/// <summary>
3753
/// Allow for tail-recursion by using a trampoline function that returns a monad with the bound value
3854
/// wrapped by `Next`, which enables decision-making about whether to keep the computation going or not.

LanguageExt.Core/Traits/Monads/Monad/Monad.Trait.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ public interface Monad<M> :
3535
//
3636
// Default implementations
3737
//
38+
39+
/// <summary>
40+
/// Lift a Next.Done value into the monad
41+
/// </summary>
42+
public static virtual K<M, Next<A, B>> Done<A, B>(B value) =>
43+
M.Pure(Next.Done<A, B>(value));
44+
45+
/// <summary>
46+
/// Lift a Next.Done value into the monad
47+
/// </summary>
48+
public static virtual K<M, Next<A, B>> Loop<A, B>(A value) =>
49+
M.Pure(Next.Loop<A, B>(value));
3850

3951
public static virtual K<M, C> SelectMany<A, B, C>(K<M, A> ma, Func<A, K<M, B>> bind, Func<A, B, C> project) =>
4052
ma.Bind(x => bind(x).Map(y => project(x, y)));

Samples/TestBed/RecurTests.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static Seq<int> insertSort(int value, Seq<int> sorted) =>
3030
public static void recurIsSameAsBind<M>(Func<K<M, int>, K<M, int>, bool>? equals = null)
3131
where M : Monad<M>
3232
{
33-
var example = toSeq(Range(1, 40000)).Strict();
33+
var example = toSeq(Range(1, 20000)).Strict();
3434

3535
Console.ForegroundColor = ConsoleColor.Yellow;
3636
Console.WriteLine("------------------------------------------------------------------------------------------");
@@ -72,15 +72,24 @@ public static void recurIsSameAsBind<M>(Func<K<M, int>, K<M, int>, bool>? equals
7272
K<M, Next<(int Total, Seq<int> Values), int>> sumTail((int Total, Seq<int> Values) pair) =>
7373
pair.Values switch
7474
{
75-
[] => M.Pure(Next.Done<(int, Seq<int>), int>(pair.Total)),
76-
var (x, xs) => M.Pure(Next.Loop<(int, Seq<int>), int>((pair.Total + x, xs)))
75+
[] => M.Done<(int, Seq<int>), int>(pair.Total),
76+
var (x, xs) => M.Loop<(int, Seq<int>), int>((pair.Total + x, xs))
7777
};
7878

79+
80+
K<M, Next<(int Total, Seq<int> Values), int>> sumTail2((int Total, Seq<int> Values) pair) =>
81+
pair.Values switch
82+
{
83+
[] => M.Done<(int, Seq<int>), int>(pair.Total),
84+
var (x, xs) => M.Loop<(int, Seq<int>), int>((pair.Total + x, xs))
85+
};
86+
7987
K<M, int> sumNoTail(Seq<int> values) =>
8088
values switch
8189
{
82-
[var x] => M.Pure(x),
83-
var (x, xs) => sumNoTail(xs) * (t => x + t)
90+
[] => M.Pure(0),
91+
var (x, xs) => from t in sumNoTail(xs)
92+
select t + x
8493
};
8594
}
8695
}

0 commit comments

Comments
 (0)