❝原文:A monad is a monoid in the category of endofunctors。 翻译:Monad 是一个 自函子 范畴 上的 幺半群” 。...❞ 这里标注了 3 个重要的概念:自函子、范畴、幺半群,这些都是数学知识,我们分开理解一下。 什么是范畴?...任何事物都是对象,大量的对象结合起来就形成了集合,对象和对象之间存在一个或多个联系,任何一个联系就叫做态射。 一堆对象,以及对象之间的所有态射所构成的一种代数结构,便称之为 范畴。 什么是函子?...我们将范畴与范畴之间的映射称之为 函子。映射是一种特殊的态射,所以函子也是一种态射。 什么是自函子? 自函子就是一个将范畴映射到自身的函子。 什么是幺半群 Monoid?...那么 1 就是单位元(乘法单位元) Ok,我们已经了解了所有应该掌握的专业术语,那就简单串解一下这段解释吧: 一个 自函子 范畴 上的 幺半群 ,可以理解为,在一个满足结合律和单位元规则的集合中,存在一个映射关系
Monad有以下特征: Monad是一种定义将函数(函子)组合起来的结构方式。 这些组合的方法都是符合结合律的。...image.png 图中表示的是一个将范畴映射到自身的自函子,而且还是一个特殊的Identity自函子。为什么这么说?...我们在这个大范畴所做的所有映射操作都是同一范畴内的映射,自然这样的范畴就是一个自函子的范畴。...单位元:存在一在 M 内的元素e,使得任一于 M 内的 a 都会符合 ae = e*a = a 。 接着我们看看在自函子的范畴上,怎么结合幺半群的定义得出Monad的。...将 F函数单独应用于C中每个函数的结果,我们就获得结果的集合的集合。 压平这两层集合,组合所有的结果。 (注意这里的组合方式将对应Monad的自然变换态射)。
Monad不就是个自函子范畴上的幺半群,这有什么难理解的(A monad is just a monoid in the category of endofunctors) —— Phillip Wadler...函子有别于函数,函数描述的是特定类型(proper type)之间的映射,而函子描述的是范畴(category)之间的映射。 那什么是范畴(category)?...Identity自函子范畴 图中表示的是一个将范畴映射到自身的自函子,而且还是一个特殊的Identity自函子。为什么这么说?...我们在这个大范畴所做的所有映射操作都是同一范畴内的映射,自然这样的范畴就是一个自函子的范畴。...单位元:存在一在 M 内的元素e,使得任一于 M 内的 a 都会符合 ae = e*a = a 。 接着我们看看在自函子的范畴上,怎么结合幺半群的定义得出Monad的。
如果一个函数既包含了我们的值,又封装了值的统一操作,使得我们可以在它限定的范围内进行任意运算,那么,我们称这种函数类型为Monad。Monad是一种高级别的思维抽象。 什么是Monad?...上面这个例子里面的Num,实际上就是一个最简单的Monad,而fmap是属于Functor(函子)的概念。...相对应的,函子就是描述一个范畴对象和另一个范畴对象间关系的态射,具体到编程语言中,函子是一个帮助我们映射一个范畴元素(比如Monad)到另一个范畴元素的函数。...群论主要是研究变换关系,群又可以分为很多种类,也有很多规律特性,这不在本文研究范围之内,读者可以自行学习相关内容。 科学解释一个Monad为自函子范畴上的幺半群。...到此,我们可以理解Monad为: 满足自函子运算(从A范畴态射到A范畴,fmap是在自己空间做映射)。 满足含幺半群的结合律。 很多函数式编程里面都会实现一个Identity函数,实际就是一个幺元素。
如果一个函数既包含了我们的值,又封装了值的统一操作,使得我们可以在它限定的范围内进行任意运算,那么,我们称这种函数类型为Monad。Monad是一种高级别的思维抽象。 3.1 什么是Monad?...上面这个例子里面的Num,实际上就是一个最简单的Monad,而fmap是属于Functor(函子)的概念。...图 49 相对应的,函子就是描述一个范畴对象和另一个范畴对象间关系的态射,具体到编程语言中,函子是一个帮助我们映射一个范畴元素(比如Monad)到另一个范畴元素的函数。...群论主要是研究变换关系,群又可以分为很多种类,也有很多规律特性,这不在本文研究范围之内,读者可以自行学习相关内容。 科学解释一个Monad为自函子范畴上的幺半群。...图 51 到此,我们可以理解Monad为: 满足自函子运算(从A范畴态射到A范畴,fmap是在自己空间做映射)。 满足含幺半群的结合律。
起初本瓜看到【单子】说白了不过就是【自函子范畴】上的一个【幺半群】而已?这句话的时候,还以为自己在看量子力学的量子纠缠相关内容,单子、函子、粒子、玻色子、费米子、绝绝子。。。...是打麻将吗。。。 好家伙~ 最后,你告诉我这句话是关于函数式编程 Monad 的解释,牛你是真滴牛!...定义: 单子由 3 个部分组成: 类型构造子 M,建造一个单子类型M T 类型转换子,经常叫做unit或return,将一个对象x嵌入到单子中: unit(x) :: T -> M T 组合子...这就像把乱七八糟的电线塞进了接线盒似的,虽然表面上看起来清爽了一些,底下的复杂性却是不可能消除的。 所以,底下的复杂性是自然。...咱们也用惰性思维去思考:现在很难理解,那我是必须要现在去理解吗?
编程语言中的基本类型 类型组合 OOP与接口类型 函数类型 函子(Functor)和单子(Monad) 1. 概述:什么是类型?为什么要引入类型的概念?...函子和单子(Functor and Monad) 概述 函子和单子的概念来自范畴论。范畴论是数学的一个分支,研究的是由对象及这些对象之间的箭头组成的结构。...由一范畴映射至其自身的函子称之为“自函子”。 在函数式编程里,函子是最重要的数据类型,也是基本的运算单位和功能单位。Functor 是实现了 map() 函数并遵守一些特定规则的容器类型。...(fmap h) 函子很强大,但是大部分主流语言都没有很好的方式来表达函子,因为函子的常规定义依赖于高阶类型(不是“高阶函数”,是“高阶类型”)的概念。...任何事物都是对象,大量的对象结合起来就形成了集合,对象和对象之间存在一个或多个联系,任何一个联系就叫做态射。 一堆对象,以及对象之间的所有态射所构成的一种代数结构,便称之为 范畴。 什么是函子?
但是,你能说清楚,它到底是什么吗? ? 网上搜索一下,你会轻松找到好多答案。 ? 上面这些说法都对,但还不够,都没有回答下面这个更深层的问题。 ? 为什么要这样做? 这就是,本文要解答的问题。...3.1 函子的概念 函子是函数式编程里面最重要的数据类型,也是基本的运算单位和功能单位。 它首先是一种范畴,也就是说,是一个容器,包含了值和变形关系。...通过 ap 函子,我们就可以实现从两个容器之中取值。它还有另外一种写法。 ? 八、Monad 函子 函子是一个容器,可以包含任何值。函子之中再包含一个函子,也是完全合法的。...Monad 函子的作用是,总是返回一个单层的函子。...I/O 是不纯的操作,普通的函数式编程没法做,这时就需要把 IO 操作写成Monad函子,通过它来完成。 ?
monad 是支持>>=操作的 applicative 函子,>>=读作绑定,它的类型是: (>>=) :: (Monad m) => m a -> (a -> m b) -> m b 即取一个 monad...和一个函数,返回一个新的 monad。...monad 有专属的类型类——Monad,其定义如下: class Applicative m => Monad (m :: * -> *) where (>>=) :: m a -> (a ->...一样,都是取一个值,把它放在能产生这个值的最小默认上下文中。...一个类型要成为 monad 不仅要满足 Monad 类型类的条件,还要满足 monad 定律(虽然编译器并不会帮你检查): 左单位元:return x >>= f 和 f x 等价 右单位元:m >>=
概念 函子 定义: 函子是一个普通对象,它实现了map函数,在遍历每个对象值的时候生成一个新对象。即,函子是一个实现了 map 契约的对象! 简单理解:函子是一个持有值的容器。...function(val){return new Container(val);} 那么我们就可以通过of创建Container: let testVal = Container.of(3);//省略new 为什么函子实现了...函子 Monad是一个含有chain方法的函子 你可以通过添加一个chain方法(或者说是join方法)扩展MayBe函子,使其成为一个Monad函子。...那么,我们就可以知道 Monad 函子的一大特点就是能够避免深层嵌套,只要提供下一运算所需要的的函数,就能将函数拆解成互相连接的多个步骤,自动进行下去,并且每次都是只返回一个单层的函子。...这个函子有一个 flatMap 方法,即降维的能力。
3.1 函子的概念 函子是函数式编程里面最重要的数据类型,也是基本的运算单位和功能单位。 它首先是一种范畴,也就是说,是一个容器,包含了值和变形关系。...通过 ap 函子,我们就可以实现从两个容器之中取值。它还有另外一种写法。 Ap.of(add(2)).ap(Maybe.of(3)); 八、Monad 函子 函子是一个容器,可以包含任何值。...如果要取出内部的值,就要连续取三次this.val。这当然很不方便,因此就出现了 Monad 函子。 Monad 函子的作用是,总是返回一个单层的函子。...I/O 是不纯的操作,普通的函数式编程没法做,这时就需要把 IO 操作写成Monad函子,通过它来完成。...如果 IO 函子是一个Monad,具有flatMap方法,那么我们就可以像下面这样调用这两个函数。 readFile('.
一个 Monad 仅仅是自函子 (endofunctor) 范畴中的一个 monoid 我们引用这句话来开场,所以把话题转到这个引言上面似乎是很合适的。...这样,当我们在编程中使用一个或多个这种值的时候,它们的行为会自然的出现,并且会使它们更方便的工作。方便的是,对你的代码的读者来说,是更有描述性和声明性的。 Monad 是一种数据结构。是一种类型。...它是一组使处理某个值变得可预测的特定行为。 回顾第 8 章,我们谈到了函子(functor):包括一个值和一个用来对构成函子的数据执行操作的类 map 实用函数。...Monad 是一个包含一些额外行为的函子(functor)。 松散接口 实际上,Monad 并不是单一的数据类型,它更像是相关联的数据类型集合。它是一种根据不同值的需要而用不同方式实现的接口。...方法都有不变且可预测的反馈,这就是 Monad,尤其是 Maybe Monad 的好处。这难道不酷吗?
Applicative好像比Monoid功能更加强大,这样,Applicative的主要用途之一应该是对可游览结构内元素进行函数施用。 4、Monad应该是泛函编程中最重要的数据类型。...泛函编程与传统的行令编程在模式上最大的分别就是在泛函编程中没有变量声明(variable declaration),变量是包嵌在一个结构里的(MyData(data)),得申明这个结构(trait MyData...无法使用行令编程模式肯定对泛函编程过程造成诸多不便,但Monad使for-comprehension成为可能,而在for-comprehension内可以实现行令编程,所以泛函编程被称为Monadic...以上的例子中for-comprehension是由Option[Int]定义的,那么,如果这个for-comprehension是由一个以上Monad组成的呢?...那么所有在for-comprehension内的表达式右方就必须是StateT类型。
接下来可以继续封装,把他们都封装成适用函子(Applicative Functor)和单子(Monad) 适用函子(Applicative Functor)根据定义: 对于任意一个函子F,如果能支持以下运算...接下来我们在看看Monad的定义。...F)->(A->F)->F复制代码 还是以Async为例,此时的Async已经有了unit和flatMap满足定义了,这个时候,就可以说Async已经是一个Monad了。...至此,我们就把Async和Result都变成了适用函子(Applicative Functor)和单子(Monad)了。 4.再说说运算符。 flatMap函数有时候会被定义为一个运算符>>=。...上面我们通过map和flatMap成功的展开了Callback hell,其实这里还有另外一个方法可以解决问题,那就是用自定义运算符。这里我们用不到适用函子的,有些问题就可能用到它。
Monad typeclass不是一种类型,而是一种程序设计模式(design pattern),是泛函编程中最重要的编程概念,因而很多行内人把FP又称为Monadic Programming。...概念在泛函编程里的重要性。...大家都说这就是三种FP的函数施用方式:在一个容器内进行函数的运算后把结果还留在容器内、得到的效果是这样的:F[A] => F[B]。只是它们分别用不同的方式提供这个施用的函数。...而且程序运算行为只会受一种类型的特性所控制。如上面所叙,Monad实例的类型控制Monadic程序的运算行为。每一种Monad实例的程序可以有不同的运算方式。...= Barbell(1,1) 现在这个自定义类型Barbell是可以跟踪当前杠铃左右重量状态的。
最大的感受是,以前对 Functor、Applicative 和 Monad 的理解太片面了。...Functor 谈 Monad(单子) 之前还是要谈谈 Functor(函子),毕竟所有的 Monad 都是 Functor。...在范畴论中,函子是范畴间的一类态射(这个定义给我的直观感受是函子指的是 fmap 函数……),数学上的概念就不多说了,下面我们来看看 Haskell 中的 Functor。...所以从 Functor 的定义来看,似乎只要实现了 fmap 函数的类型构造器,就是函子了。...事实上并不是这样,函子毕竟是一个数学概念,它必须满足函子定律: fmap id = id famp (f . g) = fmap f . fmap g id 是一个原样返回参数的函数(id x = x)
下面一步一步实现一个普通的函子: // 首先定义一个容器 由于需要new一个对象 所以这里没使用箭头函数 // 函子只跟提供map函数有关 跟类名是无关的 这里的Container也可以换成其他名称 const...另外我们常用的数组,ES6也新增了of方法,所以它也是Point函子。 深入理解Monad Monad也是一种函子,估计你看到Monad这个词你就头大了。此时你的内心:“卧槽!...又要学习一个新的函子,真心学不动了,求别更新了!!!” 其实,函子这块就是纸老虎,各种名字天花乱坠,实际上都是很简单的,Monad也不例外,先看看Monad的定义。...Monad就是一个含有chain方法的函子。...我们回顾一下这两节的内容:有map方法的对象就是函子,有of方法的函子就是Point函子,有chain方法的函子就是Monad函子。
简单来说:Monad就是泛函编程中最概括通用的数据模型(高阶数据类型)。...它不但涵盖了所有基础类型(primitive types)的泛函行为及操作,而且任何高阶类或者自定义类一旦具备Monad特性就可以与任何类型的Monad实例一样在泛函编程中共同提供一套通用的泛函编程方式...所以有人把泛函编程视作Monadic Programming也不为过之。那么,具体什么是Monad呢? ...有什么关系吗?...我们称这个抽象模型为Monad,它继承了Functor的特性,是Functor,因为Monad可以map。
经过了一段时间的泛函编程讨论,始终没能实实在在的明确到底泛函编程有什么区别和特点;我是指在现实编程的情况下所谓的泛函编程到底如何特别。...我们就以一步步更改程序状态的方式,一行一行的拼凑指令:这就是典型的行令式编程了。 泛函编程,顾名思义,就是用一个个函数来编程。讲的再深入点就是通过函数组合来更改程序状态。什么意思?为什么?...严格来讲,在泛函编程中是没有在某个地方申明一个变量,然后在一些函数里更新这个变量这种方式的。与申明变量相对应的是泛函编程会把所谓变量嵌入在一个结构里,如:F[A]。F是某种高阶类型,A就是那个变量。...既然变量封装在了套子里面,那么自然需要设计一些在套子里更新变量的函数了: 我们的目的是用某些函数把F[A]变成F[B]:A 变成了 B,但任然封装在 F[] 里: 下面我们列出几个函数,它们的操作结果都是一样的...,Applicative同时还是Monad 值得关注的是Monad特性。
Monad不就是个自函子范畴上的幺半群,这有什么难理解的。...之后,用Haskell作为过渡,最后在讲讲理论相关的内容。而第一篇作为工程部分,自然用的是大家最喜欢的Java主要是我最喜欢来讲解了。...更有意思的一件事情是,使用flatMap也可以实现join函数。也就是说,我们也能定义出Monad!...我个人认为,只是理解Monad的用途是没有必要,也没有意义去看Monad背后的数学定义的。 不过只从工程角度理解Monad是远远不够的。...文中没有提及flatMap需要遵守的规则,对Monad的定义也不太完备(缺少了return),也没有细究join和flatMap的互相实现。要真正理解Monad,理论上的内容同样是不可避免的。
领取专属 10元无门槛券
手把手带您无忧上云