在动态类型语言中有很多 monad 的实现:
一般来说,Church-Turing-Thesis 告诉我们,可以用一种语言完成的所有事情也可以用其他所有语言完成。
从上面选择的示例中您可能可以看出,我(主要)是一名 Ruby 程序员。所以,开个玩笑,我拿了上面的一个例子,用一种我完全不知道的语言重新实现了它,这通常被认为是一种不是很强大的语言,而且它似乎是唯一的编程语言在我无法找到 Monad 教程的星球上。我可以向您介绍... PHP 中的 Identity Monad:
<?php
class Identity {
protected $val;
public function __construct($val) { $this->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 的语言应该进行静态类型检查。否则编译时找不到类型错误,“复杂度”不受控制。我的理解正确吗?
你是对的,但这与单子无关。这只是一般的静态类型检查,同样适用于数组、列表甚至是普通无聊的整数。
这里还有一个红鲱鱼:如果你看一下 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 的实际类型安全性。
注意:正如@Porges 指出的那样,我上面写的仅适用于泛型类型本身。monad
您当然可以表达任何特定monad 的类型,例如List
or Maybe
,但您不能表达其Monad
自身的类型。这意味着您无法对“ List
IS-A Monad
”的事实进行类型检查,并且您无法对适用于所有实例的通用操作进行类型检查Monad
。
(请注意,即使对于 Haskell 的类型系统,除了符合 monad类型之外,检查Monad
它还遵守 monad法则可能太多了。您可能需要依赖类型,甚至可能需要一个成熟的自动定理证明器。)