为什么在即将推出的.NET 4.0中没有类似IMonad <T>的东西

Use*_*rol 29 .net c# monads

...与所有那些新的(如果我们计算IEnumerable不是那么新)与monad相关的东西?

interface IMonad<T>
{
 SelectMany/Bind();
 Return/Unit();
}
Run Code Online (Sandbox Code Playgroud)

这将允许编写以任何monadic类型操作的函数.或者它不是那么重要?

Max*_*ini 63

想想那些方法的签名IMonad<T>必须是什么.在Haskell中,Monad类型类被定义为

class Monad m where
  (>>=) :: m a -> (a -> m b) -> m b
  return :: a -> m a
Run Code Online (Sandbox Code Playgroud)

将它直接转换为C#接口是很棘手的,因为您需要能够ISpecificMonad<a>在一般IMonad接口的定义中引用特定的实现子类型("m a"或).好吧,我们不会尝试直接IEnumerable<T>实现(例如)实现IMonad<T>,而是尝试将IMonad实现分解为一个单独的对象,该对象可以与特定的monad类型实例一起传递给任何需要将其作为monad处理(这是"字典传递风格").这将是IMonad<TMonad>和TMonad在这里不是T in IEnumerable<T>,而是IEnumerable<T>它本身.但是等等-这也不能工作,因为签名Return<T>例如必须从我们获得任何类型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);
}
Run Code Online (Sandbox Code Playgroud)

使用假设的C#特性,允许我们使用类型构造函数(如TMonad <>)作为泛型类型参数.但当然C#没有这个功能(更高的多态性).您可以在runtime(typeof(IEnumerable<>))中实现类型构造函数,但不能在不给它们参数的情况下在类型签名中引用它们.因此除了-100点之外,实现这个"正确"不仅需要添加另一个普通的接口定义,而且需要对类型系统进行深入的添加.

这就是为什么能够对你自己的类型进行查询理解的能力被攻击(如果正确的魔法方法名称带有正确的签名,那么它们只是"神奇地"工作)而不是使用接口机制等.

  • 很好的答案,这是一个简短的版本:"在C#中定义Monad是不可能的,类型系统不够强大":) (10认同)
  • 在我个人看来,如果没有静态检查的副作用(即纯粹的功能),你会在相当快的时候为类型系统增加更多的复杂性,从而达到收益严重下降的程度.复杂类型系统的真正好处是能够建立程序的复杂属性/不变量,这些属性/不变量在所有情况下都被证明(而不是针对某些情况进行测试并从那里进行启发式推断),但是如果有任何函数输入/输出有一个额外的无限制"通道",类型系统没有检查,你可以证明不多. (2认同)