添加免费单子
This commit is contained in:
parent
c26fb69188
commit
bd9392ec50
|
@ -0,0 +1,75 @@
|
|||
using Sanchime.Functional.Extensions;
|
||||
using static Sanchime.Functional.Extensions.TaskExtension;
|
||||
namespace Sanchime.Functional.Monads;
|
||||
|
||||
public abstract class Free<T>
|
||||
{
|
||||
public abstract R Match<R>(Func<T, R> Done, Func<Coyo<object, Free<T>>, R> More);
|
||||
|
||||
}
|
||||
|
||||
internal sealed class Done<T> : Free<T>
|
||||
{
|
||||
public T Value { get; }
|
||||
|
||||
public Done(T value)
|
||||
=> Value = value;
|
||||
|
||||
public override R Match<R>(Func<T, R> Done, Func<Coyo<object, Free<T>>, R> More)
|
||||
=> Done(Value);
|
||||
}
|
||||
|
||||
internal sealed class More<T> : Free<T>
|
||||
{
|
||||
public Coyo<object, Free<T>> Next { get; }
|
||||
|
||||
public More(Coyo<object, Free<T>> next)
|
||||
=> Next = next;
|
||||
|
||||
public override R Match<R>(Func<T, R> Done, Func<Coyo<object, Free<T>>, R> More)
|
||||
=> More(Next);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自由单子
|
||||
/// </summary>
|
||||
public static class FreeMonad
|
||||
{
|
||||
/// <summary>
|
||||
/// 自然变幻Return, 将值导入至Free的世界
|
||||
/// </summary>
|
||||
/// <param name="value">无状态的值</param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Free<T> Return<T>(T value)
|
||||
=> Done(value);
|
||||
|
||||
/// <summary>
|
||||
/// 执行Free
|
||||
/// </summary>
|
||||
/// <param name="free">计算描述</param>
|
||||
/// <param name="interpret">解释执行</param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static T Run<T>(this Free<T> free, Func<object, object> interpret)
|
||||
=> free.Match(val => val, coyo => Run(coyo.Func(interpret(coyo.Value)), interpret));
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行Free
|
||||
/// </summary>
|
||||
/// <param name="free">计算描述</param>
|
||||
/// <param name="interpret">解释执行</param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Task<T> Run<T>(this Free<T> free, Func<object, Task<object>> interpret)
|
||||
=> free.Match<Task<T>>(val => Async(val), async coyo => await Run(coyo.Func(await interpret(coyo.Value)),interpret));
|
||||
|
||||
public static Free<T> Of<T>(object op)
|
||||
=> More(Coyo.Of<object, T>(op).Map(val => Done<T>(val)));
|
||||
|
||||
internal static Free<T> Done<T>(T value)
|
||||
=> new Done<T>(value);
|
||||
|
||||
internal static Free<T> More<T>(Coyo<object, Free<T>> value)
|
||||
=> new More<T>(value);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace Sanchime.Functional.Products;
|
||||
|
||||
public readonly struct Coyo<V, T>
|
||||
{
|
||||
public V Value {get;}
|
||||
|
||||
public Func<object, T> Func { get; }
|
||||
|
||||
public Coyo(V value, Func<object, T> func)
|
||||
=> (Value, Func) = (value, func);
|
||||
}
|
||||
|
||||
public static class Coyo
|
||||
{
|
||||
public static Coyo<V, T> Of<V, T>(V value)
|
||||
=> new Coyo<V, T>(value, x => (T)x);
|
||||
|
||||
public static Coyo<V, R> Map<V, T, R>(this Coyo<V, T> @this, Func<T, R> mapping)
|
||||
=> new Coyo<V, R>(@this.Value, x => mapping(@this.Func(x)));
|
||||
}
|
Loading…
Reference in New Issue