...所有那些新的(如果我们算上 IEnumerable 就不算新的)monad 相关的东西?
interface IMonad<T>
{
SelectMany/Bind();
Return/Unit();
}
这将允许编写对任何 monadic 类型进行操作的函数。或者它不是那么重要?
最佳答案
想想IMonad<T>
的签名是什么的方法必须是。在 Haskell 中,Monad 类型类定义为
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m a
将其直接转换为 C# 接口(interface)很棘手,因为您需要能够在通用 IMonad 接口(interface)的定义中引用特定的实现子类型(“m a”或 ISpecificMonad<a>
)。好的,而不是试图拥有(例如)IEnumerable<T>
实现 IMonad<T>
直接地,我们将尝试将 IMonad 实现分解为一个单独的对象,该对象可以与特定的 monad 类型实例一起传递给任何需要将其视为 monad 的对象(这是“字典传递样式”)。这将是 IMonad<TMonad>
这里的 TMonad 将不是 IEnumerable<T>
中的 T ,但是IEnumerable<T>
本身。但是等等——这也行不通,因为 Return<T>
的签名例如必须让我们从 any 类型 T 到 TMonad<T>
, 对于任何 TMonad<>
. IMonad 必须定义为类似
interface IMonad<TMonad<>> {
TMonad<T> Unit<T>(T x);
TMonad<U> SelectMany<T, U>(TMonad<T> x, Func<T, TMonad<U>> f);
}
使用一个假设的 C# 功能,允许我们使用类型构造器(如 TMonad<>)作为泛型类型参数。但是当然 C# 没有这个特性(higher-kinded polymorphism)。您可以在运行时具体化类型构造函数 ( typeof(IEnumerable<>)
),但不能在不给它们参数的情况下在类型签名中引用它们。因此,除了 -100 分之外,“正确”实现此功能不仅需要添加另一个普通接口(interface)定义,还需要对类型系统进行深度添加。
这就是为什么对你自己的类型进行查询理解的能力有点被黑了(如果有正确的魔术方法名称和正确的签名,它们就会“神奇地”工作)而不是使用接口(interface)机制等。
关于c# - 为什么在即将到来的 .NET 4.0 中没有像 IMonad<T> 这样的东西,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1709897/