课程

Don't fear of monads : https://www.youtube.com/watch?v=ZhuHCtR3xq8

Pure functions and side effects : https://www.youtube.com/watch?v=4IIWib5MZKg

State : https://www.youtube.com/watch?v=g8-Xrpl_Uhk

前置知识

啥是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必须满足:

  1. 结合律
  2. m (monoid op) sm = m;sm (monoid op) m = m (sm代表特殊值,一般是Unit或者0,m代表monoid集合中的东西,注意monoid不一定需要满足交换律)
  3. 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三定律