实现 Monad 的语言必须是静态类型的吗?
-
23-08-2019 - |
题
我正在学习函数式编程风格。在 不要害怕 Monad, ,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 Monad 和 Ruby (网站已关闭,但文章 可在互联网档案馆的 Wayback Machine 中找到)
- Ruby 中的 Monad 第 1 部分:身份, Ruby 中的 Monad 第 1.5 部分:身份, Ruby 中的 Monad 第 2 部分:也许(又也许不是)
- Ruby 中的 Monad
- 便宜的 Monads I:JavaScript 中的 Maybe Monad, 更多便宜的 Monad:内联自 Maybe
- Ruby 中的 Monad(语法很好!), 在 Ruby 和 Python 中列出 Monad
- Ruby 的 Haskell 风格 monad do 表示法
总的来说,丘奇图灵论告诉我们,一切可以做的事情 一 语言也可以在 所有其他 语言。
从上面选择的示例中您可能可以看出,我(主要)是一名 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 的语言应该进行静态类型检查。否则,编译时无法发现类型错误,“复杂性”不受控制。我的理解正确吗?
你是对的,但这与 monad 无关。这只是一般的静态类型检查,同样适用于数组、列表甚至普通的整数。
这里还有一个红鲱鱼:如果您查看 C#、Java 或 C 中的 monad 实现,您会发现它们比上面的 PHP 示例更长、更复杂。特别是,有 吨 类型无处不在,所以它肯定 看起来 感人的。但丑陋的事实是:C#、Java 和 C 的类型系统实际上不足以表达类型 Monad
. 。尤其, Monad
是 2 级多态类型,但 C# 和 Java 只支持 1 级多态性(他们称之为“泛型”,但实际上是同一件事),而 C 甚至不支持这一点。
所以,单子实际上是 不是 在 C#、Java 和 C 中进行静态类型检查。(例如,这就是 LINQ monad 推导式被定义为模式而不是类型的原因:因为你根本无法 表达 C# 中的类型。)静态类型系统所做的一切,只是使实现更加复杂,而没有实际帮助。它需要更复杂的类型系统(例如 Haskell 的类型系统)才能获得 monad 的实际类型安全性。
笔记:我上面写的 仅有的 适用于通用 monad
正如 @Porges 指出的那样,键入自身。你当然可以表达任何类型 具体的 单子,像 List
或者 Maybe
, ,但你不能表达类型 Monad
本身。这意味着您无法对以下事实进行类型检查:“List
IS-A Monad
”,并且您无法对适用于所有实例的通用操作进行类型检查 Monad
.
(请注意,检查 Monad
也遵守单子 法律 除了符合 monad 之外 类型 即使对于 Haskell 的类型系统来说也可能太多了。您可能需要依赖类型,甚至可能需要一个成熟的自动定理证明器。)
其他提示
这当然不是,实施单子语言的必须的静态类型的,因为你的问题问题的情况。这可能是一个好主意,为你勾勒的原因,但没有错误在编译时被检测到从未停止过任何人。只要看看有多少人写PHP。
您需要为国家单子关闭。我看着它,PHP已经关闭,因为5.3。所以这不会是一个问题了。
没有,在PHP是不可能实现的单子。你需要为关闭。从来没有少,也许的概念可仍然是有用的,当你模拟模式与课程配套:
abstract class Maybe {
abstract public function isJust();
public function isNothing(){
return !$this->isJust();
}
}
class Just extends Maybe {
protected $val = null;
public function __construct($val){
$this->val = $val;
}
public function isJust(){
return true;
}
public function getVal(){
return $this->val;
}
}
class Nothing extends Maybe {
protected $val = null;
public function __construct(){
}
public function isJust(){
return false;
}
}
function just(){
print "isJust";
}
function nothing(){
print "nothing";
}
function MaybeFunc(Maybe $arg){
if(get_class($arg) == 'Just'){
print "Just";
} else {
print "Nothing";
}
}
MaybeFunc(new Just(5));
MaybeFunc(new Nothing());