首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >String.IsNullOrEmpty Monad

String.IsNullOrEmpty Monad
EN

Stack Overflow用户
提问于 2020-07-14 12:53:35
回答 3查看 276关注 0票数 1

最近,我一直沉浸在这个迷人的函数式编程世界中,这主要是因为我在https://blog.ploeh.dk/这样的博客上积累了丰富的FP平台经验,比如React和阅读。作为一个主要的命令式程序员,这是一个有趣的转变,但我仍然试图让我的脚在我下面。

我对使用string.IsNullOrEmpty感到有点厌倦了。很多时候,我发现自己在代码中乱扔了一些表达式,比如

代码语言:javascript
复制
_ = string.IsNullOrEmpty(str) ? "default text here" : str;

这并没有那么糟糕,但是说我想把一堆选项链在这个空值之上,比如。

代码语言:javascript
复制
_ = string.IsNullOrEmpty(str) ? (
    util.TryGrabbingMeAnother() ??
    "default text here") : str;

糟透了。我宁愿吃这样的东西--

代码语言:javascript
复制
_ = monad.NonEmptyOrNull(str) ??
    util.TryGrabbingMeAnother() ??
    "default text here";

如示例所示,我使用了我所指的monad函数来帮助将string.IsNullOrEmpty还原为空链式操作:

代码语言:javascript
复制
public string NonEmptyOrNull(string source) =>
    string.IsNullOrEmpty(source) ? null : source;

我的问题是,这是恰当的术语吗?我知道Nullable<T>可以被认为是单一的(参见在C#中,Nullable可以用作函子吗?用纯英语写的蒙纳德?(对于没有FP背景的OOP程序员))。这些材料是很好的参考,但我仍然没有足够的直觉掌握主题,以了解我是否只是在这里混淆或不一致。举个例子,我知道monad应该像上面那样启用函数链,但它们也是“类型放大器”--所以我的小例子看起来就像启用链接的单曲,但是它看起来像是将空/空转换为空是一种减少而不是放大,所以我怀疑这是否实际上是一个单数。因此,对于这个特定的应用程序,一个对FP有更多经验的人能告诉我称NonEmptyOrNull为monad是否准确,为什么或者为什么不正确?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-07-19 15:59:26

这更像是一个过滤器操作。在C#中,你会习惯性地称它为Where。如果我们将缺失的值和填充的值之间的区别变得更加明确,这可能会更容易一些,这一点我们可以用可能的容器来实现。

代码语言:javascript
复制
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>());
}

只有少数几个容器支持过滤。最常见的两个是Maybe (AKA Option)和各种集合(即IEnumerable<T>)。

在Haskell (它有一个比C#更强大的类型系统)中,这是启用的通过一个名为MonadPlus的类来实现,但是我认为类型类Alternative实际上应该足够实现过滤。Alternative 被描述是应用函子上的一元。不过,我不确定这是否特别有用。

使用上面的Where方法,您可以通过类似于IsNullOrEmpty这样的检查来线程Maybe值:

代码语言:javascript
复制
var m = "foo".ToMaybe();
var inspected = m.Where(s => !string.IsNullOrEmpty(s));

这将使m不受影响,而下面的内容则不会:

代码语言:javascript
复制
var m = "".ToMaybe();
var inspected = m.Where(s => !string.IsNullOrEmpty(s));

你也可以用Nullable<T>做同样的事情,但我会把它作为练习

您也可以使用C# 8的新的可空引用类型语言特性来实现它,但我还没有尝试。

票数 1
EN

Stack Overflow用户

发布于 2020-07-14 15:06:21

单曲是由以下三部分组成的:

  • 单参数类型构造函数M
  • 一种unita -> M a函数
  • 一种joinM (M a) -> a函数

它满足了单一法则。

类型构造函数是一个类型级别的函数,它接受许多类型参数并返回一个类型。C#没有直接的这个特性,但是在编码monads时,您需要一个单参数泛型类型,例如List<T>Task<T>等。因此,对于某些泛型类型M,您需要两个函数来从单个值构造泛型类型的实例,即“平坦”类型的嵌套实例。例如,对于List<T>

代码语言:javascript
复制
public static List<T> unit<T>(T value) { return new List<T> { value }; }
public static List<T> join<T>(List<List<T>> l) { return l.SelectMany(l => l); }

从这个定义中可以看出,单个函数不能满足monad的定义,因此您的示例不是monad的示例。

根据这个定义,Nullable<T>也没有单一实例,因为不能构造嵌套类型Nullable<Nullable<T>>,因此不能实现join

票数 2
EN

Stack Overflow用户

发布于 2020-07-14 13:23:20

我认为这通常在FP范例中得到解决,这比验证null提前了一步。str值绝不能是null。相反,原始方法必须返回一个空集合。这样,方法的链接就不必验证null。下一个操作将不会执行,因为没有可操作的元素。

您可以找到多个参考资料。在互联网上与此相关。https://www.informit.com/articles/article.aspx?p=2133373&seqNum=5是我能很快抓住的

我从Pluralsight的Zoran Horvat课程上学到了这个。如果您有权限,请检查一下。课程名称为“.NET中的战术设计模式:控制流程”,该模块为“空对象和特例模式”。

考虑到对FP的兴趣,Zoran还提供了其他帮助转换或使OO代码更具功能的课程。我很兴奋在这里回应,因为最近我一直在调查FP以及。祝好运!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62895696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档