是否已经有像这样的内置功能性C#/.NET结构?g(h()),或

wz1wpwve  于 2023-05-08  发布在  .NET
关注(0)|答案(2)|浏览(137)
public static Func<V> To<T, V>(this Func<T> g, Func<T, V> h)
{
    return () => h(g());
}

public static Func<T> ToIdentity<T>(this T t)
{
    return () => t;
}

我有时会使用这些和其他延迟评估时。这些已经在.net库中了吗?

编辑:

以下是一个示例用法:

public static string SuffixColumn(this string v, string suffix, int columns)
{
    return
    v.ToIdentity()
        .ToScrubbedHtml()
        .ToFormat(() => "{0} " + suffix.ToLower().PadLeft(columns, ' '))
        .ToErrorText(v, suffix, columns)();
}

ToErrorText检查'v'是否合法(非错误代码,非空等),如果好,则运行Func中的链接,如果不好,则产生故障安全文本结果。如果v、suffix或columns不好,那么ToFormat将永远不会被调用。(因此延迟/未评估使用)。
ToFormat几乎是所提供的Func和string. Format的组合。ToIdentity用于将v提升到Func,然后链中的所有内容都基于T的某个Func。

jvlzgdj9

jvlzgdj91#

让我看看我是否理解了:你正在使用lambdas来捕获一个“ Package 器”对象中的值--一个Func<T>--然后围绕 Package 的对象构建一个惰性评估函数的工作流,是吗?

虽然用函数构建它也可以,但我个人倾向于用一些自定义类型构建monad;似乎很容易将作用于monadic类型或其“底层”类型的函数与monad本身的示例混为一谈。你基本上是在使用函数构建 identity monad;我更倾向于简单地创建一个类或接口,其名称反映了您放置身份monad的目的。
您还可以考虑重命名您的方法。您的“To”通常被称为“Bind”,您的“ToIdentity”通常被称为“Unit”。
也就是说,monad类型M<T>的monad模式通常具有以下方法:

public static M<V> Bind<U, V>(this M<U> m, Func<U, M<V>> k)

和/或

public static M<T> Unit<T>(this T value)

绑定允许您在monad上实现函数的组合,类似于在monad的“底层”类型上组合的函数。
关于C#中monads的奇妙之处的温和介绍,请参阅我以前的同事Wes Dyer关于这个主题的伟大文章:
https://learn.microsoft.com/en-us/archive/blogs/wesdyer/the-marvels-of-monads

回答您的实际问题:

这些已经在.net库中了吗?
这些功能不在框架中。但是框架中存在非常类似的功能。例如,IEnumerable<T>上的SelectMany类似于您的To方法;它实现了对序列的一元绑定操作。new Nullable<int>(123)类似于您的“ToIdentity”方法;它实现用于“可能单子”的单子单元操作。等等。
CLR类型系统不足以表达一般的monad模式;为此,你需要一个“更高”的类型系统,比如Haskell。你必须自己构建每个特定的单子。不过,看起来你已经在路上了。
关于在类C#语言中使用monad的更多想法:
C#中的monad--为什么Bind实现需要传递函数来返回一个monad?
用简单的英语说就是单子?(对于没有FP背景的OOP程序员)
为什么在即将到来的.NET 4.0中没有类似IMonad的东西
In C#, What is a monad?

lymnna71

lymnna712#

您可以使用Lazy延迟加载值。

Lazy<int> lazy = new Lazy<int>(() => delayEvaluatingMe());
int delayed = lazy.Value;

相关问题