我正在学习函数式编程风格.在" 不要害怕Monads"中,Brian Beckman对Monad进行了精彩的介绍.他提到Monad是关于功能的组合,以解决复杂性.
Monad包括
unit
将类型T转换为放大类型M(T)的函数; 和一个Bind函数,给定从T到M(U)的函数,将类型M(T)转换为另一种类型M(U).(U可以是T,但不一定是).
根据我的理解,实现monad的语言应该静态地进行类型检查.否则,在编译期间无法找到类型错误,并且不控制"复杂性".我的理解是否正确?
动态类型语言中有很多monad实现:
Ruby中的Maybe Monad
OO Monads和Ruby(网站已关闭,但该文章可在Internet Archive的Wayback Machine中找到)
Ruby中的Monads第1部分:身份,Ruby中的Monads第1.5部分:身份,Ruby中的Monads第2部分:可能(然后再次也许不是)
Ruby中的Monads
就便宜我的单子:该单子可能在JavaScript中,就便宜更多的单子:内联fromMaybe
Ruby中的Monads(语法很好!),Ruby和Python中的List Monad
用于Ruby的Haskell风格的monad符号
一般来说,Church-Turing-Thesis告诉我们,用一种语言可以完成的所有事情也可以用其他语言来完成.
正如你可以从上面的例子中选择的那样,我(大多数时候)是一个Ruby程序员.所以,就像一个笑话一样,我采用了上面的一个例子并用一种我完全不知道的语言重新实现它,这通常被认为是一种不是很强大的语言,而且似乎是唯一的编程语言在我无法找到Monad教程的星球上.我可以向你展示...... PHP中的身份Monad:
val = $val; } public static function m_return($a) { return new Identity($a); } public static function m_bind($id_a, $f) { return $f($id_a->val); } } var_dump(Identity::m_bind( Identity::m_return(1), function ($x) { return Identity::m_return($x+1); } )); ?>
没有静态类型,没有泛型,没有必要的闭包.
现在,如果你真的想要静态检查monad,那么你需要一个静态类型系统.但这或多或少是一个重言式:如果你想静态检查类型,你需要一个静态类型检查器.咄.
关于你的问题:
根据我的理解,实现monad的语言应该静态地进行类型检查.否则,在编译期间无法找到类型错误,并且不控制"复杂性".我的理解是否正确?
你是对的,但这与monads无关.这通常只是关于静态类型检查,并且同样适用于数组,列表甚至是无聊的整数.
这里还有一个红色的鲱鱼:如果你看一下C#,Java或C中monad实现的例子,它们比上面的PHP例子要长得多,也要复杂得多.特别是,有万吨的类型无处不在,所以它肯定看起来令人印象深刻.但丑陋的事实是:C#,Java和C的类型系统实际上并不足以表达类型Monad
.特别是,Monad
是一个rank-2多态类型,但C#和Java只支持rank-1多态(他们称之为"泛型",但它是一样的)并且C甚至不支持它.
因此,monad实际上不是在C#,Java和C中进行静态类型检查.(例如,LINQ monad理解被定义为模式而不是类型的原因:因为你根本无法在C#中表达类型. )所有的静态类型系统都会使实现更加复杂,而无需实际帮助.它需要一个更复杂的类型系统,如Haskell,以获得monad的实际类型安全性.
注意:我上面写的内容仅适用于泛型monad
类型,正如@Porges所指出的那样.你当然可以表达任何特定 monad 的类型,List
或者Maybe
,但是你不能表达Monad
它自己的类型.这意味着您无法对" List
IS-A Monad
"进行类型检查,也无法对所有实例上的泛型操作进行类型检查Monad
.
(请注意,检查Monad
也遵循单子法律除了符合单子类型甚至可能是太多Haskell的类型系统.你可能会需要依赖的类型,甚至一个完全成熟的自动定理证明了点.)