本文介绍了String.IsNullor Empty Monad的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我最近涉足了函数式编程的迷人世界,这主要是因为我获得了像Reaction这样的FP平台的经验,并在https://blog.ploeh.dk/之类的博客上阅读了这些经验。作为一名主要的命令式程序员,这是一个有趣的转变,但我仍然在努力摸索自己的脚步。
我有点厌倦了这样使用string.IsNullOrEmpty
。很多时候,我发现自己在代码中使用
_ = string.IsNullOrEmpty(str) ? "default text here" : str;
这并不是很糟糕,但假设我想将一系列选项链接到那个空值之后,例如
_ = string.IsNullOrEmpty(str) ? (
util.TryGrabbingMeAnother() ??
"default text here") : str;
讨厌。我宁愿要这样的东西--
_ = monad.NonEmptyOrNull(str) ??
util.TryGrabbingMeAnother() ??
"default text here";
如样例所示,我正在使用一个我称为Monad的函数来帮助将string.IsNullOrEmpty
简化为可空链的操作:
public string NonEmptyOrNull(string source) =>
string.IsNullOrEmpty(source) ? null : source;
我的问题是,这是正确的术语吗?我知道Nullable<T>
可以被认为是一个单体(参见Can Nullable be used as a functor in C#?和Monad in plain English? (For the OOP programmer with no FP background))。这些材料是很好的参考资料,但我仍然没有足够的直观把握这个主题,知道我在这里是否只是混淆或不一致。例如,我知道monad应该像我上面一样启用函数链接,但它们也是类型放大器--所以我的小示例似乎行为像是启用链接的monad,但似乎将NULL/EMPTY转换为NULL是缩减而不是放大,所以我质疑这是否实际上是。那么,对于这个特殊的应用程序,谁能告诉我,谁稍微有一点经验的FP告诉我,它是否准确地称为NonEmptyOrNull
Monad,以及为什么不是?推荐答案
这更像是筛选操作。在C#中,您可以习惯地将其称为Where
。如果我们更明确地区分缺失值和填充值,可能会更容易看到,这可以使用the Maybe container:
public static Maybe<T> Where<T>(
this Maybe<T> source,
Func<T, bool> predicate)
{
return source.SelectMany(x => predicate(x) ? x.ToMaybe() : Maybe.Empty<T>());
}
只有几个containers支持筛选。最常见的两种是Maybe
(又名Option
)和各种集合(即IEnumerable<T>
)。在Haskell(它有一个比C#更强大的类型系统)this is enabled中,通过一个名为MonadPlus
的类,但我认为类型类Alternative
实际上应该足以实现过滤。Alternative
is described作为应用函子上的么半群。我不确定这是否特别有帮助。
使用上面的Where
方法,您可以像IsNullOrEmpty
这样检查Maybe
值:
var m = "foo".ToMaybe();
var inspected = m.Where(s => !string.IsNullOrEmpty(s));
这将使m
原封不动地通过,而以下内容不会:
var m = "".ToMaybe();
var inspected = m.Where(s => !string.IsNullOrEmpty(s));
您可以使用Nullable<T>
执行相同的操作,但我将把它作为练习😉
您也可以使用C#8的新的可空引用类型语言功能来实现,但我还没有尝试过。
这篇关于String.IsNullor Empty Monad的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!