为了理解什么是Monad,最好需要了解什么是Monoid。这两篇互为姐妹篇,因为Monad的定义是:A monad is just a monoid in the category of endofunctors, what's the problem?

  what's the problem?其实问题大了去了,这个定义中首先我们知道monad是一个特殊的monoid,特殊在哪里?是在endofunctor这个范畴里,正如书桌比桌子特殊,特殊在书桌用在看书读书这个范围里。所以,我们需要首先了解什么是endofunctor,而endofunctor是end of functor的组合,还得首先了解什么是functor函子。

自函子endofunctor

  一个functor是一个多态数据类型,支持用函数对数据内容的操作,这非常类似面向对象概念中的对象,一个对象也是由数据和方法组成,方法是操作数据的函数。所以,当我们认为世界上每个都是对象时,也可以认为每个都是functor。

  一个functor是将一个范畴(广群)转换到另外一个范畴(广群),而endofunctor则是转换的源范畴和目标范畴是同一个,endofunctor是functor的特殊。

  我们知道:一个范畴是由三个部分组成: 元素对象、态射(又称为箭头)以及二元运算。如果这个范畴又满足结合律,那么它是一个半群,如果又满足幺元,那么是幺半群,也就是Monoid。

  因此,functor实际是将一个Monoid中的元素对象映射到另外一个Monoid的元素对象,态射也是这么映射。而自函子endofunctor映射的这两个Monoid是同一个。 

  在Haskell中,一个endofunctor被称为"the Hask category,",是Hask范畴。Hask范畴中的元素对象是Haskell的类型,态射箭头是Haskell的函数。

 

类型

  类型是值的集合,比如类型Bool(Haskell核心类型是大写开始)是一个有两个元素的集合,这两个元素 是True和False,类型Char是所有Unicode字符如'a'或'b'的集合。

  函数也是有类型的,函数的类型是其输入输出的综合,比如f函数是输入类型A到输出类型B:B f(A a); 在 Haskell中是如下表达:

f ∷ A → B

  因此区别两个函数的不同,我们可以从其输入类型和输出类型上区别。

  函子functor是比函数更高阶的函数,函子是作用于两个范畴之间的函数,但是根本上也是一个函数,因此函子的类型与上面的函数类型差不多。假设两个范畴是 C和D, 其函函子是:

functor F: C -> D

 

函子functor原理

  函数组合的方式有其特殊地方,这个特殊主要是由于我们组合的对象是函数,如果组合的对象是整数类型,两个整数组合成一个整数,这没有问题,但是你不能将两个函数类型组合起来还是和原来函数类型一样。比如我们将两个f函数f ∷ A → B组合起来,就不会得到还是A → B。

  函子functor是比函数更高阶的函数,函子是作用于两个范畴之间的函数,可以简单认为是两个集合之间的映射。范畴的映射转换需要转换其中的元素和态射。

  假设两个范畴是 C和D, 有一个函子functor F: C -> D ,这种写法类似函数写法,但是因为函子是范畴的函数,所以,其工作原理是进入范畴C和D内部,而范畴是由元素对象和态射箭头组成,因此函子就要分别作用于元素对象和态射箭头。

  映射元素对象:C中的任何对象A转变成了D中的F(A);
  映射态射箭头:C中的态射f: A -> B转变成了D中的F(f): F(A) -> F(B) 。  
  (组合箭头和元箭头映射这里省略)

http://www.jdon.com/idea/monad.html

什么是Monad?的更多相关文章

  1. Functional Programming without Lambda - Part 2 Lifting, Functor, Monad

    Lifting Now, let's review map from another perspective. map :: (T -> R) -> [T] -> [R] accep ...

  2. Atitit 理解Monad attilax总结

    Atitit 理解Monad attilax总结 但函数式编程最大的一个问题是,函数是一个数学抽象,在现实世界中不存在,1 那既然这样就够用了,还要 Monad 干嘛?Monad 的作用在这里就体现出 ...

  3. Scalaz(41)- Free :IO Monad-Free特定版本的FP语法

    我们不断地重申FP强调代码无副作用,这样才能实现编程纯代码.像通过键盘显示器进行交流.读写文件.数据库等这些IO操作都会产生副作用.那么我们是不是为了实现纯代码而放弃IO操作呢?没有IO的程序就是一段 ...

  4. Scalaz(32)- Free :lift - Monad生产线

    在前面的讨论里我们提到自由数据结构就是产生某种类型的最简化结构,比如:free monoid, free monad, free category等等.我们也证明了List[A]是个free mono ...

  5. Scalaz(28)- ST Monad :FP方式适用变量

    函数式编程模式强调纯代码(pure code),主要实现方式是使用不可变数据结构,目的是函数组合(composability)最终实现函数组件的重复使用.但是,如果我们在一个函数p内部使用了可变量(m ...

  6. Scalaz(25)- Monad: Monad Transformer-叠加Monad效果

    中间插播了几篇scalaz数据类型,现在又要回到Monad专题.因为FP的特征就是Monad式编程(Monadic programming),所以必须充分理解认识Monad.熟练掌握Monad运用.曾 ...

  7. Scalaz(20)-Monad: Validation-Applicative版本的Either

    scalaz还提供了个type class叫Validation.乍看起来跟\/没什么分别.实际上这个Validation是在\/的基础上增加了Applicative功能,就是实现了ap函数.通过Ap ...

  8. Scalaz(19)- Monad: \/ - Monad 版本的 Either

    scala标准库提供了一个Either类型,它可以说是Option的升级版.与Option相同,Either也有两种状态:Left和Right,分别对应Option的None和Some,不同的是Lef ...

  9. Scalaz(18)- Monad: ReaderWriterState-可以是一种简单的编程语言

    说道FP,我们马上会联想到Monad.我们说过Monad的代表函数flatMap可以把两个运算F[A],F[B]连续起来,这样就可以从程序的意义上形成一种串型的流程(workflow).更直白的讲法是 ...

  10. Scalaz(17)- Monad:泛函状态类型-State Monad

    我们经常提到函数式编程就是F[T].这个F可以被视为一种运算模式.我们是在F运算模式的壳子内对T进行计算.理论上来讲,函数式程序的运行状态也应该是在这个运算模式壳子内的,也是在F[]内更新的.那么我们 ...

随机推荐

  1. Sql Server创建外键失败

    问题: 已成功保存“PPR_BasicInformation”表“PPR_PS”表- 无法创建关系“FK_PPR_PS_PPR_BasicInformation”. ALTER TABLE 语句与 F ...

  2. Windows 10 Mobile 演示:插入耳机自动执行 APP

    Windows Mobile 10 新特性:插入外部设备自动动作(如插入耳机执行 APP.打开小工具):另外可以找到最后一次使用设备地点和时间: http://www.tudou.com/progra ...

  3. 51nod 1268 和为K的组合 dfs

    题目: 1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 给出N个正整数组成的数组A,求能否从中选出若干个,使他们的和为K.如果可以,输出:& ...

  4. 51nod 1098 最小方差 排序+前缀和+期望方差公式

    题目: 题目要我们,在m个数中,选取n个数,求出这n个数的方差,求方差的最小值. 1.我们知道,方差是描述稳定程度的,所以肯定是着n个数越密集,方差越小. 所以我们给这m个数排个序,从连续的n个数中找 ...

  5. 转 c#中 base64字符串与普通字符串互转

    https://blog.csdn.net/hwt0101/article/details/79758912 转成 Base64 形式的 System.String:    string a = &q ...

  6. Dapper基础知识一

    在下刚毕业工作,之前实习有用到Dapper?这几天新项目想用上Dapper,在下比较菜鸟,这块只是个人对Dapper的一种总结. 1,什么是Dapper?     Dapper,.NET下的一种ORM ...

  7. CentOS7-1810 系统DNS服务器BIND软件配置说明

    DNS的出现的历史 网络出现的早期是使用IP地址通讯的,那时就几台主机通讯.但是随着接入网络主机的增多,这种数字标识的地址非常不便于记忆,UNIX上就出现了建立一个叫做hosts的文件(Linux和W ...

  8. Sublime Text编辑器配置Python解释器简易教程

    前天在微信上遇到一个小伙伴问我一个关于Sublime text配置Python解释器的问题,可能是初学者,对这方面还不是很懂,想使用快捷键但是徒劳一场,因为缺少Python解释器,直接按下快捷键Ctr ...

  9. HDU-5025 Saving Tang Monk 广度搜索 状态压缩

    题目链接:https://cn.vjudge.net/problem/HDU-5025 题意 救唐僧,路上有m(<=9)把钥匙,最多5条蛇和一个唐僧. 目标是前往唐僧的地方,用全部钥匙打开全部的 ...

  10. redis为什么选择单线程工作模型

    1.先说一下为什么出现进程,线程 进程:在计算机发明之初就发现,在输入数据时(I/O速度慢),CPU是空闲的,这样就浪费了CPU资源,为了充分利用CPU资源,发明了进程,在输入程序A的数据时,程序B在 ...