我试图制定一个单一的定义,而不需要数学术语或Haskell来理解。
monad是否可以被认为是一个函数,它接受一个值并封装它,使其满足特定的接口和行为约束,而这些约束在功能风格中是有用的?
接口约束是:
它有一个类型构造函数来定义它的类型(这是什么?)
二、它具有一个单位函数,它将一个值转换为相应的一元类型。
三、它有一个"bind“方法,它接受一个monad,一个接受某种类型并返回monad的函数(这是另一个monad吗?),并返回monad。
行为上的制约因素是:
一.左身份
Monad(x).bind(fn) == Monad(fn(x)); // for all x, fn二、权利同一性
Monad(x).bind(function(x){return x;}) == Monad(x); // for all x三、结合性
Monad(x).bind(fn1).bind(fn2) == Monad(x).bind(function(x) {
return fn2(fn1(x));
});这是单曲的最小定义吗?
发布于 2016-07-08 15:42:46
梅森的回答是正确的,是的,你应该读我的系列。为了更彻底地强调他的观点:
是否可以将monad看作是接受值并封装它从而满足特定接口和行为约束的函数?
是的,但这并不是描述单曲的最好方式。不过,你很亲近,我们可以对你的配方做一些小的改动,得到一个更好的特性。
您可以说monad称为M,它是一个接受值并生成包装值的函数。这是有问题的。更确切地说,单曲具有这样的功能。monad M是三种东西的集合:
M<T>,我们有一个类型的int,我们生成一个新的类型的M<int>。unit,它接受T类型的值并生成M<T>类型的值。bind,它接受M<T>类型的值和从T到M<U>的函数,并生成M<U>。第二件事是你的“函数,它接受一个值并包装它”。不是说monad就是这个函数;monad是一元类型构造器本身、包装器和函数的组合,它将一个新函数绑定到一元工作流的末尾。
这就是为什么在范畴理论中,单子有时被称为“三元组”,因为你需要三样东西来描述一个单子。
现在,您将注意到,我做的事情与您相同;在我的系列文章中,我将monad描述为遵循某些规则的泛型类型;也就是说,我说monad是第一件事,而第一件事本身必须有第二件和第三件事。
我们如何准确地描述各个部分之间的关系并不重要;重要的是必须有以下三种东西:一种“放大”类型的方法,一种“包装”值的方法,以及一种通过“绑定”函数将单个实例转换为另一种类型的方法。如果你有这三样东西,而且它们遵守了身份、传递性等明显的规则,那么你就有了一个单位制。
发布于 2016-07-05 15:23:38
埃里克·利珀特( Eric )写的关于单曲的大系列实际上是以一种对非Haskellers有意义的方式来解释这些问题的。整件事值得一读,但基本思想如下:
monad是一种“类型增强器”,它采用基本类型并对其进行一些新的操作(例如将类型T转换为类似于IEnumerable<T>的序列),具有以下特征:
monad是一个泛型
M<T>,因此:
T并返回一个M<T>。我们一直将其描述为一种带有签名static M<T> CreateSimpleM<T>(T t)的方法static M<R> ApplySpecialFunction<A, R>(M<A> monad, Func<A, M<R>> function)最后,这两种方法都必须遵守一元定律,即:
如果这个定义看起来有点混乱,那么下一段解释为什么:
呼!现在你也许明白了为什么我在几周前开始这个系列的想法是通过看例子来探索模式,而不是从单一法则开始。
如果您从第一个岗位开始并阅读本系列文章,那么这个概念最终应该是有意义的。谢天谢地,这里没有“一只狗就像一只热狗”的废话!
发布于 2016-07-05 14:31:15
( i)它是一个接受类型并返回新类型(即泛型类型)的函数,我不确定它在js中是否会直接使用,因为您没有类型
)将返回不同的类型,但以相同的方式返回,即您可以从m a -> m b重新设计
这是一个极小的定义,但是通常还有其他函数,例如,每个monad都是一个函子,所以您总是可以为您的monad定义fmap,而且您通常有一个连接/扁平函数(绑定可以根据fmap和join实现)。
https://softwareengineering.stackexchange.com/questions/324033
复制相似问题