【发布时间】:2020-11-03 19:40:57
【问题描述】:
我最近涉足函数式编程的迷人世界,主要是因为获得了 React 等 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 是 reduction 而不是放大,所以我质疑这是否真的 is 一个 monad。那么对于这个特定的应用程序,有更多 FP 经验的人能否告诉我将 NonEmptyOrNull 称为 monad 是否准确,为什么或为什么不准确?
【问题讨论】:
-
NonEmpty和Option(或Nullable)都是 monad,因此您可以将它们组合起来以获得所需的类型。一般来说,你不能组成 monad,但你可以编写一个函数,通过另一个 monad 的语义来扩展一个 monad。这种方法被称为单子变换器。无论如何,我建议你先学习仿函数和应用仿函数,因为 monad 也是仿函数,而后者决定了它们大约 80% 的语义。如果您有兴趣,我一直在编写 FP 课程。
标签: c# string functional-programming null monads