调整文件所属

This commit is contained in:
sanchime 2023-01-08 13:34:54 +08:00
parent 7fbb363176
commit 627f2e83a1
15 changed files with 128 additions and 60 deletions

1
.gitignore vendored
View File

@ -29,3 +29,4 @@ x64/
*.vspscc *.vspscc
*.vssscc *.vssscc
.builds .builds
.fake

View File

@ -7,11 +7,11 @@ public static class OptionExtension
#region : #region :
public static Option<R> Map<T, R>(this None _, Func<T, R> mapping) // public static Option<R> Map<T, R>(this None _, Func<T, R> mapping)
=> Option.None; // => Option.None;
public static Option<R> Map<T, R>(this Some<T> some, Func<T, R> mapping) // public static Option<R> Map<T, R>(this Some<T> some, Func<T, R> mapping)
=> Option.Some(mapping(some.Value)); // => Option.Some(mapping(some.Value));
public static Option<R> Map<T, R>(this Option<T> option, Func<T, R> mapping) public static Option<R> Map<T, R>(this Option<T> option, Func<T, R> mapping)
=> option.Match(() => Option.None, (val) => Option.Some(mapping(val))); => option.Match(() => Option.None, (val) => Option.Some(mapping(val)));

View File

@ -8,7 +8,7 @@ public static class Either
=> new(right); => new(right);
} }
public readonly struct Either<TLeft, TRight> public readonly partial struct Either<TLeft, TRight> : IEither<TLeft, TRight>
{ {
internal TLeft? Left { get; } internal TLeft? Left { get; }
internal TRight? Right { get; } internal TRight? Right { get; }
@ -48,28 +48,3 @@ public readonly struct Either<TLeft, TRight>
public override string ToString() public override string ToString()
=> Match(l => $"Left({l})", r => $"Right({r})"); => Match(l => $"Left({l})", r => $"Right({r})");
} }
public readonly struct Left<TLeft>
{
internal TLeft Value { get; }
internal Left(TLeft value)
=> Value = value;
public override string ToString()
=> $"Left({Value})";
}
public readonly struct Right<TRight>
{
internal TRight Value { get; }
internal Right(TRight value)
=> Value = value;
public override string ToString()
=> $"Right({Value})";
public Right<TRRight> Map<TLeft, TRRight>(Func<TRight, TRRight> mapping)
=> Either.Right(mapping(Value));
public Either<TLeft, TRRight> Bind<TLeft, TRRight>(Func<TRight, Either<TLeft, TRRight>> binding)
=> binding(Value);
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Sanchime.Functional.Products;
public interface IEither<TLeft, TRight> : IEither, IFunctor
{
}
public interface IEither
{
}

View File

@ -0,0 +1,10 @@
namespace Sanchime.Functional.Products;
public readonly struct Left<TLeft> : IEither
{
internal TLeft Value { get; }
internal Left(TLeft value)
=> Value = value;
public override string ToString()
=> $"Left({Value})";
}

View File

@ -0,0 +1,17 @@
namespace Sanchime.Functional.Products;
public readonly struct Right<TRight> : IEither
{
internal TRight Value { get; }
internal Right(TRight value)
=> Value = value;
public override string ToString()
=> $"Right({Value})";
public Right<TRRight> Map<TLeft, TRRight>(Func<TRight, TRRight> mapping)
=> Either.Right(mapping(Value));
public Either<TLeft, TRRight> Bind<TLeft, TRRight>(Func<TRight, Either<TLeft, TRRight>> binding)
=> binding(Value);
}

View File

@ -4,6 +4,13 @@ namespace Sanchime.Functional.Products;
/// 应用函子 /// 应用函子
/// </summary> /// </summary>
/// <typeparam name="TCategory"></typeparam> /// <typeparam name="TCategory"></typeparam>
public interface IApplicative<TCategory> : IFunctor<TCategory> public interface IApplicative<TCategory> : IApplicative, IFunctor<TCategory>
where TCategory : ICategory
{ {
} }
public interface IApplicative : IFunctor
{
}

View File

@ -5,17 +5,14 @@ namespace Sanchime.Functional.Products;
/// 同一范畴内不同对象之间的映射 /// 同一范畴内不同对象之间的映射
/// </summary> /// </summary>
/// <typeparam name="TCategory"></typeparam> /// <typeparam name="TCategory"></typeparam>
public interface IFunctor<TCategory> : ICategory public interface IFunctor<TCategory> : IFunctor
where TCategory : ICategory
{ {
TCategory Map(Func<TCategory, TCategory> mapping); TCategory Map<T>(Func<T, TCategory> mapping);
} }
public struct Test<T> : IFunctor<Test<T>> public interface IFunctor : ICategory
{ {
public T? Value {get; set; }
public Test<T> Map(Func<Test<T>, Test<T>> mapping)
{
return mapping(this);
}
} }

View File

@ -5,5 +5,6 @@ namespace Sanchime.Functional.Products;
/// </summary> /// </summary>
/// <typeparam name="TCategory"></typeparam> /// <typeparam name="TCategory"></typeparam>
public interface IMonad<TCategory> : IApplicative<TCategory> public interface IMonad<TCategory> : IApplicative<TCategory>
where TCategory : ICategory
{ {
} }

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Sanchime.Functional.Products;
public interface IOption : ICategory
{
}
public interface IOption<TValue> : IOption
{
TValue Value { get; }
}

View File

@ -0,0 +1,9 @@
namespace Sanchime.Functional.Products;
/// <summary>
/// <see cref="Option"/>的<see cref="None"/>状态
/// </summary>
public readonly partial struct None : IOption
{
internal static readonly None Default = new();
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Sanchime.Functional.Products;
public readonly partial struct None : IFunctor<None>
{
public None Map<T>(Func<T, None> mapping)
=> Option.None;
}

View File

@ -1,30 +1,12 @@
namespace Sanchime.Functional.Products; namespace Sanchime.Functional.Products;
/// <summary>
/// <see cref="Option"/>的<see cref="None"/>状态
/// </summary>
public readonly struct None
{
internal static readonly None Default = new();
}
/// <summary>
/// <see cref="Option"/>的<see cref="Some"/>状态
/// </summary>
/// <typeparam name="TValue"></typeparam>
public readonly struct Some<TValue>
{
internal TValue Value { get; }
internal Some(TValue value) => Value = value ?? throw new ArgumentNullException(nameof(value), "不能在Some状态中包装null值, 应该使用None");
}
public static class Option public static class Option
{ {
public static None None => None.Default; public static None None => None.Default;
public static Option<TValue> Some<TValue>(TValue value) => new Some<TValue>(value); public static Option<TValue> Some<TValue>(TValue value) => new Some<TValue>(value);
} }
public readonly struct Option<TValue> : IEquatable<None>, IEquatable<Option<TValue>> public readonly partial struct Option<TValue> : IOption<TValue>, IEquatable<None>, IEquatable<Option<TValue>>
{ {
private readonly TValue _value; private readonly TValue _value;

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Sanchime.Functional.Products.Options;
public readonly partial struct Option<TValue> //: IFunctor<IOption>
{
}

View File

@ -0,0 +1,14 @@
namespace Sanchime.Functional.Products;
/// <summary>
/// <see cref="Option"/>的<see cref="Some"/>状态
/// </summary>
/// <typeparam name="TValue"></typeparam>
public readonly struct Some<TValue> : IOption, IFunctor
{
internal TValue Value { get; }
internal Some(TValue value) => Value = value ?? throw new ArgumentNullException(nameof(value), "不能在Some状态中包装null值, 应该使用None");
public Option<Some<TValue>> Map(Func<TValue, Some<TValue>> mapping)
=> Option.Some(mapping(this.Value));
}