课程
Don't fear of monads : https://www.youtube.com/watch?v=ZhuHCtR3xq8
Pure functions and side effects : https://www.youtube.com/watch?v=4IIWib5MZKg
前置知识
啥是Functional programming
在函数式编程中,任意代码都被看作是数据,如
int x;
static a f<a> (a x) {...}
都是数据
pure/impure functions
pure functions : 对于相同的输入给予相同的输出以及不改变程序的state的函数
例子
add x y = x + y
这个函数是纯的
add_and_print x y = print (x+y)
这个函数是不纯的,因为它改变了当前程序的state(屏幕输出)
add_random x = x + random
这个函数也是不纯的,因为它对于相同的输入给予不同的输出
side effects
在“pure/impure functions”中的add_random
函数中的random就是side effects,因为他改变了当前函数的state,进而改变了整个函数的state
pure function不会产生side effects
side effects无害,不被预期的side effects有害
Monad的出现解决了什么问题?
有了monad,我们可以更加精准的控制side effects从而使其更加可控
Monoid
我们假设
f :: a -> a
g :: a -> a
x :: a
现在我们想将两种不同的东西结合在一起
那么显然有如下写法(假设给予的param为x,默认为左结合)
f (g x)
g (f x)
现在我们想创建一个新的函数
(f (.) g) x = f (g x)
左侧消掉a,右侧为h,即
f (.) g = h
那么显然,h的类型为a -> a
这就是Monoid的表现形式之一
Monoid所需的东西:一个集合和一个数据与另一个数据所绑定的规则(在上面这个实例中体现为两个数据必须含有相同的类型)
Monoid必须满足:
- 结合律
m (monoid op) sm = m;sm (monoid op) m = m
(sm代表特殊值,一般是Unit或者0,m代表monoid集合中的东西,注意monoid不一定需要满足交换律)id :: a -> a;f :: a -> a;f (monoid op) id = f
Monad
Monad可以视为monoid的扩展
一个monad可以由类型m T和两个操作组成
return :: a -> m a
bind :: m a -> (a -> m b) -> m b
monad也满足monoid三定律