为什么需要monad

269 views
Skip to first unread message

Fei Wang

unread,
May 8, 2014, 7:17:59 AM5/8/14
to sca...@googlegroups.com
看了很多文章,尤其是monad are elephant之后,对monad有了一个算是比较全面的了解
也写了一些实验代码,但是我不晓得,为什么前人会想出这样的东西,他们是怎么样的思路。
我看很多地方都说纯函数的副作用,不确定性?尤其是haskell语言中,可惜我不是很懂haskell
不晓得组里有人能科普下,为什么monad在函数式编程特别重要,他是基于什么思路一点点的引出来的呢

Liu Sam

unread,
May 8, 2014, 10:04:47 PM5/8/14
to sca...@googlegroups.com
这个……看来你研究得比较深入了啊,我不太理解为什么需要 monad,看那个monad are elephant 的介绍中好象就是 map 和 flattenMap 之类的应用,函数式语言的特色嘛,函数被作为第一公民来对待,可以当参数,可以当返回结果,这也就只是我目前的理解,通俗了说就是用函数再组合出更牛的函数,用 monad 的方式包装起来用。这里分享一个之前转发的文章(http://wind13.lofter.com/post/b2b9b_f33079),不太理解作者说的内容,呵呵……也许对你能有些什么启发吧!

Best regards!

Sam Liu



--
您收到此邮件是因为您订阅了Google网上论坛中的“Scala中文社区”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到scalacn+u...@googlegroups.com
要发帖到此论坛,请发送电子邮件至sca...@googlegroups.com
要查看更多选项,请访问https://groups.google.com/d/optout

Fei Wang

unread,
May 8, 2014, 11:00:10 PM5/8/14
to sca...@googlegroups.com
好的,我看一下,目前我能理解的是Monad是一个类型容器,它解决IO还要靠延迟求值,但是不晓得
为什么非要一个类型容器
--
Cheers,
王飞

Xiang Zhang

unread,
May 8, 2014, 11:03:07 PM5/8/14
to sca...@googlegroups.com
to making imperative programming in functional programming.

纯函数编程是不能有副作用的,所有IO操作都有副作用,改变了状态,monad通过高阶函数来模拟这个过程。

Fei Wang

unread,
May 8, 2014, 11:48:02 PM5/8/14
to sca...@googlegroups.com
能给点伪代码吗

Xiang Zhang

unread,
May 8, 2014, 11:56:34 PM5/8/14
to sca...@googlegroups.com
我不熟悉scala,我是用F#的,不过我最近开发的一款产品Alea.cuBase (http://www.quantalea.net) 就是采用的 monad来定义GPU 程序,比如:

let gpuTemplate = cuda {
   let! kernel1 = <@ fun x y -> ....  @> |> Compiler.DefineKernel
   let! kernel2 = <@ fun x y -> .... @> |> Compiler.DefineKernel
   return Entry(fun program -> ...) }

这里 cuda 就是一个定义的monad,里面的let binding是用的 let! ,这样就定义了一系列的定义函数,但并没有编译GPU代码,所以我称之为 template.
接下来我可以开始编译GPU code:

let program = Compiler.load gpuTemplate Worker

这样,这个template就被编译了,而我们之前的各个definekernel将会被这里执行.

Xiang Zhang

unread,
May 8, 2014, 11:59:34 PM5/8/14
to sca...@googlegroups.com
你可以去网上搜索一下 state monad

Xiang Zhang

unread,
May 9, 2014, 12:15:39 AM5/9/14
to sca...@googlegroups.com
补充说一下,也许一开始就接触I/O monad可能不是很习惯,建议可以先搜索一下 maybe monad 和 state monad,然后再阅读一下monad的blog,就会比较清楚一点,我个人感觉,monad实际上是一些高阶函数的嵌套。

Caoyuan

unread,
May 9, 2014, 4:16:17 AM5/9/14
to sca...@googlegroups.com
为什么会有monad这些东西,我在微博上断断续续说过一些,贴在这里:

单从monad是这样那样,能这样那样,去理解monad,确实像盲人摸象,很难把握它。可如果你跳出来,想像什么样的东西能够作为最基本的单元来概括运算的本质,不管它是值的运算、还是类型的运算、不管是什么类型或者类型的类型,或者是运算的运算,可能能帮助你理解为什么monad会是这个样子。

一种东西变换之后还是自己,但又不会完全是自己,因为需要能引入新的能力。同时它们串起来能处理所有问题,而问题本身又可以表达为自己,同时可以串起来被处理。

monad就是一个通用的combinator interface。//@GeniusVczh: 这个东西就是combinator

要实现这种变换,可以先从虚空中想像出一种context,不管里面怎么变,出来还是这个它。最简单的就是“有(Just)”和“无(Nothing)”,都归类为Maybe,然后是List之类的集合,再往上,包括运算本身比如Functor,Applicative等,最后终于到了IO。//@邓草原: 而monad就是一个通用的combinator interface

Fei Wang

unread,
May 9, 2014, 5:27:27 AM5/9/14
to sca...@googlegroups.com

2014-05-09 16:16 GMT+08:00 Caoyuan <dcao...@gmail.com>:
这个东西就是combinator

这个总结有点击中我的感觉了,我就是觉得Monad是极其抽象的,它什么都可以包,而且一旦包上去
就脱不下来了​



--
Cheers,
王飞

Fei Wang

unread,
May 9, 2014, 5:37:02 AM5/9/14
to sca...@googlegroups.com
如果有人用Monad和非Monad的方式来对比一段程序(哪怕是伪代码),由浅入深,估计我这种新手更好理解,主要FP里面的理论太多
其实说combinator,我还是得去了解下combinator是什么


2014-05-09 16:16 GMT+08:00 Caoyuan <dcao...@gmail.com>:



--
Cheers,
王飞

Caoyuan

unread,
May 9, 2014, 5:41:19 AM5/9/14
to sca...@googlegroups.com

Fei Wang

unread,
May 9, 2014, 7:17:12 AM5/9/14
to sca...@googlegroups.com
对了,这里这个combinator和那个传说中的Y combinator是一回事吗


2014-05-09 16:16 GMT+08:00 Caoyuan <dcao...@gmail.com>:



--
Cheers,
王飞

Xiang Zhang

unread,
May 9, 2014, 7:42:12 AM5/9/14
to sca...@googlegroups.com
说monad确实让人云里雾里,所以在F#里,微软将其称为computation expression,又称为workflow,我觉得这更容易让大众理解一些。

tao

unread,
May 9, 2014, 7:55:42 AM5/9/14
to sca...@googlegroups.com
确实,不要为一个看起来奇怪的词而纠结。不要被名字吓到了。。。

-- 
tao
Sent with Sparrow

tao

unread,
May 9, 2014, 7:20:15 AM5/9/14
to sca...@googlegroups.com
你想多了。。。

-- 
tao
Sent with Sparrow

hao huang

unread,
May 8, 2014, 10:34:51 PM5/8/14
to sca...@googlegroups.com
我是最近才开始了解scala。提供点资料,希望有用。

这本书“Functional programming in scala"有这么一段:

Functional programming (FP) is based on a simple premise with far-reaching
implications: We construct our programs using only pure functions. In other words,
functions that have no side effects. What does this mean exactly? Performing any
of the following actions directly would involve a side effect:
* Reassigning a variable
* Modifying a data structure in place
* Setting a field on an object
* Throwing an exception or halting with an error
* Printing to the console or reading user input
* Reading from or writing to a file
* Drawing on the screen

用来解决这些side effects都需要monad,例如Option, Either, Future/Promise。

这有个video的课程,讲师之一是Martin Odersky。
你可以直接从第三周开始看:Monads and Effects

谢谢



--

Xuefeng Wu

unread,
May 9, 2014, 11:20:35 AM5/9/14
to sca...@googlegroups.com
monad 可以很简单,也可以很复杂。像Haskell的IO是比较复杂的应用,可以先从简单的开始理解。



像Scala 的 Option, Future都是Monad, 甚至我觉得Actor也是某种形式的monad.




2014-05-08 19:17 GMT+08:00 Fei Wang <pyth...@gmail.com>:

--
您收到此邮件是因为您订阅了Google网上论坛中的“Scala中文社区”论坛。
要退订此论坛并停止接收此论坛的电子邮件,请发送电子邮件到scalacn+u...@googlegroups.com
要发帖到此论坛,请发送电子邮件至sca...@googlegroups.com
要查看更多选项,请访问https://groups.google.com/d/optout



--

~Yours, Xuefeng Wu/吴雪峰  敬上

杨博

unread,
May 14, 2014, 11:36:49 PM5/14/14
to sca...@googlegroups.com
Haskell原生语法有限制,禁止你执行有副作用的代码。哪怕是Scala中简单一句println("Hello, world!"),Haskell都做不到。

所以Haskell必须用Monad来绕过这个限制。但是用基本语法使用Monad时,代码比较繁琐,所以Haskell又发明了关键字do配合Monad。

Scala没有什么副作用的限制,所以Scala不需要Monad也能完成一切Monad能完成的工作。

不过,Scala原生的副作用操作都是同步操作,在进行高并发编程时,性能不好。所以如果在Scala中实现类似Monad的模型,就可以执行异步操作,来提高性能。

我有一个库就在Scala中实现了和Monad相同的函数模型。这个库是stateless-future(https://github.com/Atry/stateless-future),欢迎使用。

这里有一个例子,用stateless-future(相当于Haskell的Monad)实现了一个简单的TCP服务端和客户端:


在 2014年5月8日星期四UTC+8下午7时17分59秒,Fei Wang写道:

东东

unread,
Mar 29, 2015, 6:50:27 AM3/29/15
to sca...@googlegroups.com
有全面了解了怎么可能还不知道它的意义在哪里.........矛盾


在 2014年5月8日星期四 UTC+8下午7:17:59,Fei Wang写道:

Hongbin Lin

unread,
Mar 30, 2015, 10:11:29 AM3/30/15
to sca...@googlegroups.com
Monad就好比加减算术,很多人知道怎么算加法,但是也不知道它的意义在哪。

FRANK LI

unread,
Aug 26, 2020, 9:40:50 PM8/26/20
to Scala中文社区
因为monad是一个很常见的代数结构

Xiang Zhang

unread,
Aug 27, 2020, 4:38:00 AM8/27/20
to sca...@googlegroups.com
这个帖子都是六年前的了。
举个简单的例子,print(“hello”),这个其实就是改变了世界,英文新的文字被打印出来了,这不符合函数编程一切都是不可变的(你不能改变世界),用monad,每次print,其实都是创造了新的世界,原来的世界并没有改变。

Monad 的用途很多,比如前面提到的异步操作,每个语句都是异步产生结果,你没法实时计算,所有你用monad提供一系列函数,他们将异步进行计算。monad 可以看作是一个高阶函数。
--
您收到此邮件是因为您订阅了Google网上论坛上的“Scala中文社区”群组。
要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到scalacn+u...@googlegroups.com
要在网络上查看此讨论,请访问https://groups.google.com/d/msgid/scalacn/5e2b6f7f-167b-4d4c-b5ba-41eba2fc1ab0n%40googlegroups.com

Xuan Jiang

unread,
Jul 18, 2021, 9:25:48 PM7/18/21
to Scala中文社区
想请教一下这是不是在config 文件里加一行beame.agentsim.agents.Vehicles.SharedFleets.reposition = "min-availability-undersupply-algorithm"
3735549A-5A85-4E3D-A25B-552B516E0A3F.jpeg
Reply all
Reply to author
Forward
0 new messages