首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >最小程序员对monad的定义

最小程序员对monad的定义
EN

Software Engineering用户
提问于 2016-07-05 14:18:42
回答 4查看 1.5K关注 0票数 6

我试图制定一个单一的定义,而不需要数学术语或Haskell来理解。

monad是否可以被认为是一个函数,它接受一个值并封装它,使其满足特定的接口和行为约束,而这些约束在功能风格中是有用的?

接口约束是:

它有一个类型构造函数来定义它的类型(这是什么?)

二、它具有一个单位函数,它将一个值转换为相应的一元类型。

三、它有一个"bind“方法,它接受一个monad,一个接受某种类型并返回monad的函数(这是另一个monad吗?),并返回monad。

行为上的制约因素是:

一.左身份

代码语言:javascript
运行
复制
Monad(x).bind(fn) == Monad(fn(x)); // for all x, fn

二、权利同一性

代码语言:javascript
运行
复制
Monad(x).bind(function(x){return x;}) == Monad(x); // for all x

三、结合性

代码语言:javascript
运行
复制
Monad(x).bind(fn1).bind(fn2) == Monad(x).bind(function(x) {
  return fn2(fn1(x));
});

这是单曲的最小定义吗?

EN

回答 4

Software Engineering用户

回答已采纳

发布于 2016-07-08 15:42:46

梅森的回答是正确的,是的,你应该读我的系列。为了更彻底地强调他的观点:

是否可以将monad看作是接受值并封装它从而满足特定接口和行为约束的函数?

是的,但这并不是描述单曲的最好方式。不过,你很亲近,我们可以对你的配方做一些小的改动,得到一个更好的特性。

您可以说monad称为M,它是一个接受值并生成包装值的函数。这是有问题的。更确切地说,单曲具有这样的功能。monad M是三种东西的集合:

  • 接受类型并生成新类型的转换。在C#中,我们将这种转换称为“泛型类型”。我们有一个通用类型的M<T>,我们有一个类型的int,我们生成一个新的类型的M<int>
  • 泛型函数unit,它接受T类型的值并生成M<T>类型的值。
  • 泛型函数bind,它接受M<T>类型的值和从TM<U>的函数,并生成M<U>

第二件事是你的“函数,它接受一个值并包装它”。不是说monad就是这个函数;monad是一元类型构造器本身、包装器和函数的组合,它将一个新函数绑定到一元工作流的末尾。

这就是为什么在范畴理论中,单子有时被称为“三元组”,因为你需要三样东西来描述一个单子。

现在,您将注意到,我做的事情与您相同;在我的系列文章中,我将monad描述为遵循某些规则的泛型类型;也就是说,我说monad是第一件事,而第一件事本身必须有第二件和第三件事。

我们如何准确地描述各个部分之间的关系并不重要;重要的是必须有以下三种东西:一种“放大”类型的方法,一种“包装”值的方法,以及一种通过“绑定”函数将单个实例转换为另一种类型的方法。如果你有这三样东西,而且它们遵守了身份、传递性等明显的规则,那么你就有了一个单位制。

票数 12
EN

Software Engineering用户

发布于 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)的方法
  • 此外,还有一些将基础类型应用到该类型的monad中的函数。我们一直将其描述为一种具有签名的方法:

static M<R> ApplySpecialFunction<A, R>(M<A> monad, Func<A, M<R>> function)最后,这两种方法都必须遵守一元定律,即:

  • 将构造函数应用于monad的给定实例会产生一个逻辑上相同的monad实例。
  • 将函数应用于值上的构造函数的结果,并将该函数直接应用于值,将产生两个在逻辑上相同的monad实例。
  • 对一个值应用第一个函数,然后对结果应用第二个函数,并将第三个函数应用到原始值,该第三个函数是第一个和第二个函数的组合,从而产生两个逻辑上相同的monad实例。

如果这个定义看起来有点混乱,那么下一段解释为什么:

呼!现在你也许明白了为什么我在几周前开始这个系列的想法是通过看例子来探索模式,而不是从单一法则开始。

如果您从第一个岗位开始并阅读本系列文章,那么这个概念最终应该是有意义的。谢天谢地,这里没有“一只狗就像一只热狗”的废话!

票数 8
EN

Software Engineering用户

发布于 2016-07-05 14:31:15

( i)它是一个接受类型并返回新类型(即泛型类型)的函数,我不确定它在js中是否会直接使用,因为您没有类型

)将返回不同的类型,但以相同的方式返回,即您可以从m a -> m b重新设计

这是一个极小的定义,但是通常还有其他函数,例如,每个monad都是一个函子,所以您总是可以为您的monad定义fmap,而且您通常有一个连接/扁平函数(绑定可以根据fmap和join实现)。

票数 2
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/324033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档