调整Option
This commit is contained in:
parent
59f4e8c110
commit
8b4aae1d63
|
@ -0,0 +1,13 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Rider ignored files
|
||||
/contentModel.xml
|
||||
/projectSettingsUpdater.xml
|
||||
/modules.xml
|
||||
/.idea.Sanchime.iml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
|
@ -0,0 +1 @@
|
|||
Sanchime
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -6,5 +6,5 @@ namespace Sanchime.Functional.Extensions;
|
|||
public static class DictionaryExtension
|
||||
{
|
||||
public static Option<T> Lookup<K, T>(this Dictionary<K, T> dictionary, K key) where K: notnull
|
||||
=> dictionary.TryGetValue(key, out T? value) ? Option.Some(value) : Option.None;
|
||||
=> dictionary.TryGetValue(key, out T? value) ? Optional.Some(value) : Optional.None;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ namespace Sanchime.Functional.Extensions;
|
|||
public static class EnumExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 将字符串转换为相应的枚举值的<see cref="Option"/
|
||||
/// 将字符串转换为相应的枚举值的<see cref="Optional"/
|
||||
/// </summary>
|
||||
public static Option<T> Parse<T>(this string @this) where T : struct
|
||||
=> Enum.TryParse(@this, out T val) ? Option.Some(val) : Option.None;
|
||||
=> Enum.TryParse(@this, out T val) ? Optional.Some(val) : Optional.None;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ public static class IEnumerableExtension
|
|||
public static Func<T, IEnumerable<T>> Return<T>() => t => List(t);
|
||||
|
||||
/// <summary>
|
||||
/// 将序列内第一条元素转换为<see cref="Option"/>
|
||||
/// 将序列内第一条元素转换为<see cref="Optional"/>
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
|
@ -20,14 +20,14 @@ public static class IEnumerableExtension
|
|||
{
|
||||
if (source is null)
|
||||
{
|
||||
return Option.None;
|
||||
return Optional.None;
|
||||
}
|
||||
var first = source.FirstOrDefault();
|
||||
return first is not null ? Option.Some(first) : Option.None;
|
||||
return first is not null ? Optional.Some(first) : Optional.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 给定谓词,查询序列内第一条数据并将其转换为<see cref="Option"/>
|
||||
/// 给定谓词,查询序列内第一条数据并将其转换为<see cref="Optional"/>
|
||||
/// </summary>
|
||||
/// <param name="source">数据源</param>
|
||||
/// <param name="predicate">谓词</param>
|
||||
|
@ -37,14 +37,14 @@ public static class IEnumerableExtension
|
|||
{
|
||||
if (source is null)
|
||||
{
|
||||
return Option.None;
|
||||
return Optional.None;
|
||||
}
|
||||
var first = source.Where(predicate).FirstOrDefault();
|
||||
return first is not null ? Option.Some(first) : Option.None;
|
||||
return first is not null ? Optional.Some(first) : Optional.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将序列内最后一个元素转换为<see cref="Option"/>
|
||||
/// 将序列内最后一个元素转换为<see cref="Optional"/>
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
|
@ -53,14 +53,14 @@ public static class IEnumerableExtension
|
|||
{
|
||||
if (source is null)
|
||||
{
|
||||
return Option.None;
|
||||
return Optional.None;
|
||||
}
|
||||
var tail = source.LastOrDefault();
|
||||
return tail is not null ? Option.Some(tail) : Option.None;
|
||||
return tail is not null ? Optional.Some(tail) : Optional.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 给定谓词,查询序列内最后一条数据并将其转换为<see cref="Option"/>
|
||||
/// 给定谓词,查询序列内最后一条数据并将其转换为<see cref="Optional"/>
|
||||
/// </summary>
|
||||
/// <param name="source">数据源</param>
|
||||
/// <param name="predicate">谓词</param>
|
||||
|
@ -70,10 +70,10 @@ public static class IEnumerableExtension
|
|||
{
|
||||
if (source is null)
|
||||
{
|
||||
return Option.None;
|
||||
return Optional.None;
|
||||
}
|
||||
var last = source.Where(predicate).LastOrDefault();
|
||||
return last is not null ? Option.Some(last) : Option.None;
|
||||
return last is not null ? Optional.Some(last) : Optional.None;
|
||||
}
|
||||
|
||||
public static R Match<T, R>(this IEnumerable<T> source, Func<R> Empty, Func<T, IEnumerable<T>, R> Otherwise)
|
||||
|
|
|
@ -3,8 +3,8 @@ namespace Sanchime.Functional.Extensions;
|
|||
public static class NullableExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 将<see cref="Nullable"/>值转换为<see cref="Option"/>
|
||||
/// 将<see cref="Nullable"/>值转换为<see cref="Optional"/>
|
||||
/// </summary>
|
||||
public static Option<T> ToOption<T>(this Nullable<T> @this) where T : struct
|
||||
=> @this.HasValue ? Option.Some(@this.Value) : Option.None;
|
||||
=> @this.HasValue ? Optional.Some(@this.Value) : Optional.None;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ namespace Sanchime.Functional.Extensions;
|
|||
|
||||
public static class OptionExtension
|
||||
{
|
||||
public static Unit Match<T>(this Option<T> option, Action None, Action<T> Some)
|
||||
=> option.Match(None.ToFunc(), Some.ToFunc());
|
||||
|
||||
|
||||
#region 函子: 同一范畴内不同对象之间的态射
|
||||
|
||||
|
@ -13,27 +12,18 @@ public static class OptionExtension
|
|||
// public static Option<R> Map<T, R>(this Some<T> some, Func<T, R> mapping)
|
||||
// => Option.Some(mapping(some.Value));
|
||||
|
||||
public static Option<R> Map<T, R>(this Option<T> option, Func<T, R> mapping)
|
||||
=> option.Match(() => Option.None, (val) => Option.Some(mapping(val)));
|
||||
// public static Option<R> Map<T, R>(this Option<T> option, Func<T, R> mapping)
|
||||
// => option.Match(() => Option.None, (val) => Option.Some(mapping(val)));
|
||||
|
||||
// public static Option<Func<T2, R>> Map<T1, T2, R>(this Option<T1> option, Func<T1, T2, R> mapping)
|
||||
// public static IOption Map<T1, T2, R>(this Option<T1> option, Func<T1, T2, R> mapping)
|
||||
// => option.Map(mapping.Curry());
|
||||
|
||||
// public static Option<Func<T2, T3, R>> Map<T1, T2, T3, R>(this Option<T1> option, Func<T1, T2, T3, R> mapping)
|
||||
// public static IOption Map<T1, T2, T3, R>(this Option<T1> option, Func<T1, T2, T3, R> mapping)
|
||||
// => option.Map(mapping.CurryFirst());
|
||||
#endregion
|
||||
|
||||
#region 单子: 自函子范畴上的幺半群
|
||||
|
||||
/// <summary>
|
||||
/// Return自然变换: 将上下文无关的值导入至上下文有关的世界
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Option<T> Return<T>(T value)
|
||||
=> value is null ? Option.None : Option.Some(value);
|
||||
|
||||
|
||||
public static Option<R> Bind<T, R>(this Option<T> option, Func<T, Option<R>> binding)
|
||||
=> option.Match(() => new Option<R>(), binding);
|
||||
|
@ -46,12 +36,12 @@ public static class OptionExtension
|
|||
|
||||
// #region 应用函子
|
||||
|
||||
// public static Option<R> Apply<T, R>(this Option<Func<T, R>> option, Option<T> value)
|
||||
// => option.Match(
|
||||
// None: () => Option.None,
|
||||
// Some: (apply) => value.Match(
|
||||
// None: () => Option.None,
|
||||
// Some: (val) => Option.Some(apply(val))));
|
||||
public static Option<R> Apply<T, R>(this Option<Func<T, R>> option, Option<T> value)
|
||||
=> option.Match(
|
||||
None: () => Optional.None,
|
||||
Some: (apply) => value.Match(
|
||||
None: () => Optional.None,
|
||||
Some: (val) => Optional.Some(apply(val))));
|
||||
|
||||
// public static Option<Func<T2, R>> Apply<T1, T2, R>(this Option<Func<T1, T2, R>> option, Option<T1> value)
|
||||
// => option.Map(CurryingExtension.Curry).Apply(value);
|
||||
|
@ -95,7 +85,7 @@ public static class OptionExtension
|
|||
=> left.Match(() => right(), (_) => left);
|
||||
|
||||
/// <summary>
|
||||
/// 将<see cref="Option"转为<see cref="Either"/>
|
||||
/// 将<see cref="Optional"转为<see cref="Either"/>
|
||||
/// </summary>
|
||||
/// <param name="option"></param>
|
||||
/// <param name="error"></param>
|
||||
|
@ -111,18 +101,18 @@ public static class OptionExtension
|
|||
|
||||
#region Linq式
|
||||
|
||||
// public static Option<R> Select<T, R>(this Option<T> source, Func<T, R> mapping)
|
||||
// => source.Map(mapping);
|
||||
public static IOption Select<T, R>(this Option<T> source, Func<T, R> mapping)
|
||||
=> source.Map(mapping);
|
||||
|
||||
public static Option<T> Where<T, R>(this Option<T> source, Func<T, bool> predicate)
|
||||
=> source.Match(() => Option.None, (val) => predicate(val) ? source : Option.None);
|
||||
=> source.Match(() => Optional.None, (val) => predicate(val) ? source : Optional.None);
|
||||
|
||||
public static Option<RR> SelectMany<T, R, RR>(this Option<T> source, Func<T, Option<R>> binding, Func<T, R, RR> project)
|
||||
=> source.Match(
|
||||
None: () => Option.None,
|
||||
None: () => Optional.None,
|
||||
Some: (val) => binding(val).Match(
|
||||
None: () => Option.None,
|
||||
Some: (res) => Option.Some(project(val, res))));
|
||||
None: () => Optional.None,
|
||||
Some: (res) => Optional.Some(project(val, res))));
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ public interface IEither<TLeft, TRight> : IEither
|
|||
|
||||
}
|
||||
|
||||
public interface IEither : IFunctor
|
||||
public interface IEither
|
||||
{
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
namespace Sanchime.Functional.Products;
|
||||
|
||||
/// <summary>
|
||||
/// 应用函子
|
||||
/// </summary>
|
||||
/// <typeparam name="TCategory"></typeparam>
|
||||
public interface IApplicative<TCategory> : IApplicative, IFunctor<TCategory>
|
||||
where TCategory : ICategory
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public interface IApplicative : IFunctor
|
||||
{
|
||||
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
namespace Sanchime.Functional.Products;
|
||||
|
||||
public interface ICategory
|
||||
{
|
||||
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
namespace Sanchime.Functional.Products;
|
||||
|
||||
/// <summary>
|
||||
/// 函子
|
||||
/// 同一范畴内不同对象之间的映射
|
||||
/// </summary>
|
||||
/// <typeparam name="TCategory"></typeparam>
|
||||
public interface IFunctor<TCategory, TValue> : IFunctor
|
||||
where TCategory : ICategory
|
||||
{
|
||||
TCategory Map<TResult>(Func<TValue, TResult> mapping);
|
||||
}
|
||||
|
||||
public interface IFunctor<TCategory> : IFunctor
|
||||
where TCategory : ICategory
|
||||
{
|
||||
TCategory Map<TValue, TResult>(Func<TValue, TResult> mapping);
|
||||
}
|
||||
|
||||
public interface IFunctor : ICategory
|
||||
{
|
||||
public TResult Map<TResult>(Func<ICategory, TResult> mapping)
|
||||
=> mapping(this);
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
namespace Sanchime.Functional.Products;
|
||||
|
||||
/// <summary>
|
||||
/// 单子
|
||||
/// </summary>
|
||||
/// <typeparam name="TCategory"></typeparam>
|
||||
public interface IMonad<TCategory> : IApplicative<TCategory>
|
||||
where TCategory : ICategory
|
||||
{
|
||||
}
|
|
@ -5,12 +5,16 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Sanchime.Functional.Products;
|
||||
|
||||
public interface IOption : IFunctor
|
||||
public interface IOption
|
||||
{
|
||||
bool IsSome { get; }
|
||||
}
|
||||
|
||||
public interface IOption<TValue> : IOption, IFunctor<IOption, TValue>
|
||||
/// <summary>
|
||||
/// 选项
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue">选项内部维护的值</typeparam>
|
||||
public interface IOption<out TValue> : IOption
|
||||
{
|
||||
TValue Value { get; }
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
namespace Sanchime.Functional.Products;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Option"/>的<see cref="None"/>状态
|
||||
/// <see cref="Optional"/>的<see cref="None"/>状态
|
||||
/// </summary>
|
||||
public readonly partial struct None : IOption
|
||||
{
|
||||
/// <summary>
|
||||
/// 静态构造形成单例
|
||||
/// </summary>
|
||||
static None() { }
|
||||
public bool IsSome => false;
|
||||
internal static readonly None Default = new();
|
||||
}
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
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<TValue, TResult>(Func<TValue, TResult> mapping)
|
||||
=> Option.None;
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
using Sanchime.Functional.Extensions;
|
||||
|
||||
namespace Sanchime.Functional.Products;
|
||||
|
||||
public static class Option
|
||||
public static class Optional
|
||||
{
|
||||
public static None None => None.Default;
|
||||
public static Option<TValue> Some<TValue>(TValue value) => new Some<TValue>(value);
|
||||
|
@ -18,39 +20,39 @@ public readonly partial struct Option<TValue> : IOption<TValue>, IEquatable<None
|
|||
=> (_isSome, _value) = (true, value ?? throw new ArgumentNullException(nameof(value)));
|
||||
|
||||
/// <summary>
|
||||
/// 将<see cref="None"/>转换为<see cref="Option"/>
|
||||
/// 将<see cref="None"/>转换为<see cref="Optional"/>
|
||||
/// </summary>
|
||||
/// <param name="_"></param>
|
||||
public static implicit operator Option<TValue>(None _)
|
||||
=> new();
|
||||
|
||||
/// <summary>
|
||||
/// 将<see cref="Some"/>转换为<see cref="Option"/>
|
||||
/// 将<see cref="Some"/>转换为<see cref="Optional"/>
|
||||
/// </summary>
|
||||
/// <param name="some"></param>
|
||||
public static implicit operator Option<TValue>(Some<TValue> some)
|
||||
=> new(some.Value);
|
||||
|
||||
/// <summary>
|
||||
/// 将常规值提升至<see cref="Option"/>
|
||||
/// 将常规值提升至<see cref="Optional"/>
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public static implicit operator Option<TValue>(TValue value)
|
||||
=> value is null ? Option.None : Option.Some(value);
|
||||
=> value is null ? Optional.None : Optional.Some(value);
|
||||
|
||||
public bool IsSome => this.Match(() => false, (_) => true);
|
||||
public bool IsSome => _isSome;
|
||||
|
||||
/// <summary>
|
||||
/// 获取<see cref="Option"/>内部的值,如果为<see cref="Option.None"/>则抛出异常
|
||||
/// 获取<see cref="Optional"/>内部的值,如果为<see cref="Optional.None"/>则抛出异常
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TValue ValueUnsafe => this.Match(() => throw new InvalidOperationException(), val => val);
|
||||
|
||||
/// <summary>
|
||||
/// 获取<see cref="Option"/>内部的值,如果为<see cref="Option.None"/>则返回默认值
|
||||
/// 获取<see cref="Optional"/>内部的值,如果为<see cref="Optional.None"/>则返回默认值
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TValue Value => this.Match(() => default!, val => val);
|
||||
public TValue Value => _isNone ? default! : _value;
|
||||
|
||||
/// <summary>
|
||||
/// 转换为序列
|
||||
|
@ -60,15 +62,7 @@ public readonly partial struct Option<TValue> : IOption<TValue>, IEquatable<None
|
|||
{
|
||||
if (_isSome) yield return _value;
|
||||
}
|
||||
/// <summary>
|
||||
/// 接收两个函数,根据<see cref="Option"/>的状态进行求值
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult"></typeparam>
|
||||
/// <param name="None">None状态</param>
|
||||
/// <param name="Some">Some状态</param>
|
||||
/// <returns></returns>
|
||||
public TResult Match<TResult>(Func<TResult> None, Func<TValue, TResult> Some)
|
||||
=> _isSome ? Some(_value) : None();
|
||||
|
||||
|
||||
public bool Equals(Option<TValue> other)
|
||||
=> this._isSome == other._isSome
|
||||
|
|
|
@ -2,18 +2,39 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Sanchime.Functional.Extensions;
|
||||
|
||||
namespace Sanchime.Functional.Products;
|
||||
|
||||
public readonly partial struct Option<TValue>
|
||||
public static class OptionFunctor
|
||||
{
|
||||
/// <summary>
|
||||
/// 接收两个函数,根据<see cref="Optional"/>的状态进行求值
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult"></typeparam>
|
||||
/// <param name="None">None状态</param>
|
||||
/// <param name="Some">Some状态</param>
|
||||
/// <returns></returns>
|
||||
public static TResult Match<TValue, TResult>(this IOption<TValue> option, Func<TResult> None, Func<TValue, TResult> Some)
|
||||
=> option.IsSome ? Some(option.Value) : None();
|
||||
|
||||
public static Unit Match<TValue>(this IOption<TValue> option, Action None, Action<TValue> Some)
|
||||
=> option.Match(None.ToFunc(), Some.ToFunc());
|
||||
|
||||
/// <summary>
|
||||
/// 映射
|
||||
/// </summary>
|
||||
/// <param name="option"></param>
|
||||
/// <param name="mapping"></param>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <typeparam name="TResult"></typeparam>
|
||||
/// <returns></returns>
|
||||
public IOption Map<TResult>(Func<TValue, TResult> mapping)
|
||||
=> this.Match(() => Option.None, value => Option.Some(mapping(value)));
|
||||
public static IOption<TResult> Map<TValue, TResult>(this IOption<TValue> option, Func<TValue, TResult> mapping)
|
||||
=> option.Match(() => Optional.None, value => Optional.Some(mapping(value)));
|
||||
|
||||
public static IOption<Func<TValue1, TResult>> Map<TValue, TValue1, TResult>(this IOption<TValue> option,Func<TValue, TValue1, TResult> mapping)
|
||||
=> option.Map(mapping.Curry());
|
||||
|
||||
public static IOption<Func<TValue1, TValue2, TResult>> Map<TValue, TValue1, TValue2, TResult>(this IOption<TValue> option, Func<TValue, TValue1, TValue2, TResult> mapping)
|
||||
=> option.Map(mapping.CurryFirst());
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
namespace Sanchime.Functional.Products;
|
||||
|
||||
public readonly partial struct Option<TValue>
|
||||
{
|
||||
/// <summary>
|
||||
/// Return自然变换: 将上下文无关的值导入至上下文有关的世界
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IOption Return<T>(T value)
|
||||
=> value is null ? Optional.None : Optional.Some(value);
|
||||
|
||||
public static IOption Return(TValue value)
|
||||
=> Return<TValue>(value);
|
||||
}
|
|
@ -1,16 +1,15 @@
|
|||
namespace Sanchime.Functional.Products;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Option"/>的<see cref="Some"/>状态
|
||||
/// <see cref="Optional"/>的<see cref="Some"/>状态
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public readonly struct Some<TValue> : IOption<TValue>
|
||||
public readonly struct Some<TValue> : IOption
|
||||
{
|
||||
public bool IsSome => Value is not null;
|
||||
public TValue Value { get; }
|
||||
internal Some(TValue value) => Value = value ?? throw new ArgumentNullException(nameof(value), "不能在Some状态中包装null值, 应该使用None");
|
||||
|
||||
|
||||
public IOption Map<TResult>(Func<TValue, TResult> mapping)
|
||||
=> Option.Some(mapping(this.Value));
|
||||
=> Optional.Some(mapping(this.Value));
|
||||
}
|
||||
|
|
|
@ -3,38 +3,51 @@ using Sanchime.Functional.Extensions;
|
|||
using Sanchime.Toolkits;
|
||||
|
||||
|
||||
void foo(Option<int> option)
|
||||
try
|
||||
{
|
||||
void foo(Option<int> option)
|
||||
{
|
||||
var res = option.Map(x => x + 2);
|
||||
res.WriteLine();
|
||||
}
|
||||
"预计打印Some(12)".WriteLine();
|
||||
foo(10);
|
||||
"预计打印None".WriteLine();
|
||||
foo(Option.None);
|
||||
}
|
||||
|
||||
"预计打印Char".WriteLine();
|
||||
Option.Some(1)
|
||||
.Map(x => (float)x + 1.2)
|
||||
"预计打印Some(12)".WriteLine();
|
||||
foo(10);
|
||||
"预计打印None".WriteLine();
|
||||
foo(Optional.None);
|
||||
|
||||
"预计打印Some(String)".WriteLine();
|
||||
Optional.Some(1)
|
||||
.Map(x => x + 1.2)
|
||||
.Map(x => x.ToString())
|
||||
.Map(x => x.GetType().Name)
|
||||
.ForEach(x => x.WriteLine());
|
||||
.WriteLine();
|
||||
|
||||
// 测试Option的Bind
|
||||
var parse = (string s) => Int32.TryParse(s, out int i) ? Option.Some(i) : Option.None;
|
||||
var foo1 = (string s) => s.Pipe(parse).Bind(Age.Of);
|
||||
|
||||
foo1("111").WriteLine();
|
||||
foo1("aaa").WriteLine();
|
||||
foo1("123").WriteLine();
|
||||
var parse = (string s) => Int32.TryParse(s, out int i) ? Optional.Some(i) : Optional.None;
|
||||
var foo1 = (string s) => s.Pipe(parse).Bind(Age.Of);
|
||||
"预计打印Some(111)".WriteLine();
|
||||
foo1("111").WriteLine();
|
||||
"预计打印None".WriteLine();
|
||||
foo1("aaa").WriteLine();
|
||||
"预计打印Some(123)".WriteLine();
|
||||
foo1("123").WriteLine();
|
||||
// 管道
|
||||
foo1("1ab").Pipe(x => Console.WriteLine(x));
|
||||
"预计打印None".WriteLine();
|
||||
foo1("1ab").Pipe(x => x.WriteLine());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Message.WriteLine();
|
||||
ex.StackTrace.WriteLine();
|
||||
}
|
||||
|
||||
public struct Age
|
||||
{
|
||||
private int _value;
|
||||
|
||||
public static Option<Age> Of(int age)
|
||||
=> IsValid(age) ? Option.Some(new Age(age)) : Option.None;
|
||||
=> IsValid(age) ? Optional.Some(new Age(age)) : Optional.None;
|
||||
|
||||
private Age(int age)
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@ public static class Basic
|
|||
{
|
||||
public static void WriteLine<T>(this T @this)
|
||||
{
|
||||
Debug.WriteLine(@this);
|
||||
Console.WriteLine(@this);
|
||||
}
|
||||
|
||||
public static void WriteLine<T>(this T @this, Func<T, T> func)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sanchime/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
Loading…
Reference in New Issue