我正在学习函数式编程风格。在 不要害怕 Monad, ,Brian Beckman 对 Monad 进行了精彩的介绍。他提到 Monad 是关于函数的组合,以解决复杂性。

一个 Monad 包括一个 unit 将类型 T 转换为放大类型 M(T) 的函数;Bind 函数,给定从 T 到 M(U) 的函数,将类型 M(T) 转换为另一种类型 M(U)。(U 可以是 T,但不一定)。

根据我的理解,实现 monad 的语言应该进行静态类型检查。否则,编译时无法发现类型错误,“复杂性”不受控制。我的理解正确吗?

有帮助吗?

解决方案

动态类型语言中有很多 monad 的实现:

总的来说,丘奇图灵论告诉我们,一切可以做的事情 语言也可以在 所有其他 语言。

从上面选择的示例中您可能可以看出,我(主要)是一名 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());
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top