From bd9392ec507de1ff8546f4acb0035e7972241b90 Mon Sep 17 00:00:00 2001 From: Sanchime Date: Sat, 14 May 2022 18:43:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=85=8D=E8=B4=B9=E5=8D=95?= =?UTF-8?q?=E5=AD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sanchime.Functional/Monads/FreeMonad.cs | 75 +++++++++++++++++++++++++ Sanchime.Functional/Products/Coyo.cs | 20 +++++++ 2 files changed, 95 insertions(+) create mode 100644 Sanchime.Functional/Monads/FreeMonad.cs create mode 100644 Sanchime.Functional/Products/Coyo.cs diff --git a/Sanchime.Functional/Monads/FreeMonad.cs b/Sanchime.Functional/Monads/FreeMonad.cs new file mode 100644 index 0000000..6721cd0 --- /dev/null +++ b/Sanchime.Functional/Monads/FreeMonad.cs @@ -0,0 +1,75 @@ +using Sanchime.Functional.Extensions; +using static Sanchime.Functional.Extensions.TaskExtension; +namespace Sanchime.Functional.Monads; + +public abstract class Free +{ + public abstract R Match(Func Done, Func>, R> More); + +} + +internal sealed class Done : Free +{ + public T Value { get; } + + public Done(T value) + => Value = value; + + public override R Match(Func Done, Func>, R> More) + => Done(Value); +} + +internal sealed class More : Free +{ + public Coyo> Next { get; } + + public More(Coyo> next) + => Next = next; + + public override R Match(Func Done, Func>, R> More) + => More(Next); +} + +/// +/// 自由单子 +/// +public static class FreeMonad +{ + /// + /// 自然变幻Return, 将值导入至Free的世界 + /// + /// 无状态的值 + /// + /// + public static Free Return(T value) + => Done(value); + + /// + /// 执行Free + /// + /// 计算描述 + /// 解释执行 + /// + /// + public static T Run(this Free free, Func interpret) + => free.Match(val => val, coyo => Run(coyo.Func(interpret(coyo.Value)), interpret)); + + /// + /// 异步执行Free + /// + /// 计算描述 + /// 解释执行 + /// + /// + public static Task Run(this Free free, Func> interpret) + => free.Match>(val => Async(val), async coyo => await Run(coyo.Func(await interpret(coyo.Value)),interpret)); + + public static Free Of(object op) + => More(Coyo.Of(op).Map(val => Done(val))); + + internal static Free Done(T value) + => new Done(value); + + internal static Free More(Coyo> value) + => new More(value); +} diff --git a/Sanchime.Functional/Products/Coyo.cs b/Sanchime.Functional/Products/Coyo.cs new file mode 100644 index 0000000..c46971f --- /dev/null +++ b/Sanchime.Functional/Products/Coyo.cs @@ -0,0 +1,20 @@ +namespace Sanchime.Functional.Products; + +public readonly struct Coyo +{ + public V Value {get;} + + public Func Func { get; } + + public Coyo(V value, Func func) + => (Value, Func) = (value, func); +} + +public static class Coyo +{ + public static Coyo Of(V value) + => new Coyo(value, x => (T)x); + + public static Coyo Map(this Coyo @this, Func mapping) + => new Coyo(@this.Value, x => mapping(@this.Func(x))); +}