...与所有那些新的(如果我们计算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点之外,实现这个"正确"不仅需要添加另一个普通的接口定义,而且需要对类型系统进行深入的添加.
这就是为什么能够对你自己的类型进行查询理解的能力被攻击(如果正确的魔法方法名称带有正确的签名,那么它们只是"神奇地"工作)而不是使用接口机制等.
| 归档时间: |
|
| 查看次数: |
4704 次 |
| 最近记录: |