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。
2条答案
按热度按时间jvlzgdj91#
让我看看我是否理解了:你正在使用lambdas来捕获一个“ Package 器”对象中的值--一个
Func<T>
--然后围绕 Package 的对象构建一个惰性评估函数的工作流,是吗?虽然用函数构建它也可以,但我个人倾向于用一些自定义类型构建monad;似乎很容易将作用于monadic类型或其“底层”类型的函数与monad本身的示例混为一谈。你基本上是在使用函数构建 identity monad;我更倾向于简单地创建一个类或接口,其名称反映了您放置身份monad的目的。
您还可以考虑重命名您的方法。您的“To”通常被称为“Bind”,您的“ToIdentity”通常被称为“Unit”。
也就是说,monad类型
M<T>
的monad模式通常具有以下方法:和/或
绑定允许您在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?
lymnna712#
您可以使用Lazy延迟加载值。