函数式语言的计算模型 - Monoids
Posted 计算科学的道与术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数式语言的计算模型 - Monoids相关的知识,希望对你有一定的参考价值。
Monoids 是Category Theory中的一个定义
主要是说,一个操作具有Associative的特性,所谓Associative特性,
就是这个操作是可以复合的。
所谓可以组合,就是不管是 A * B * C 还是 B * C * A
他们最后的结果是一样的
好比 1 + 1 + 2 + 3 = 7
那么 1 + (1 + 2 + 3) = 1 + 6 = 7
1 + (1 + (2 + 3)) = 1 + (1 + 5) = 1 + 6 = 7
如果我们把这些加数作为一个List
(1,2,3,4)
在这个list上面做一个加法,也就是+的操作
在Scala里面,就是
list(1,2,3,4).foldRight(0)(_ + _)
那么如果是顺序变一下呢?就是
list(1,2,3,4).foldLeft(0)(_ + _)
其实也是一样的结果。
这些foldLeft和foldRight都是叫做是一种Monoids
那么我们说这个有什么用呢?
那么如果在这个List非常长的情况下,我们的计算复杂度是O(n)
但是怎么降低时间复杂度呢?
就是要用并行计算了
因为是计算顺序无关
那么我们可以把这些计算,split & merge
每一个部分都作为一个分布式计算的单元,并行计算,最后合并结果
那么就是
list(....).parMap(_ + _)
这样从DLS的层面就enforce了计算的时间和模型。
并行计算的时间复杂度是多少呢?就是O(1)
每一个单元都是non-blocking的计算模型,最后用Latch合并
但是作为DSL来说,抽象的Monoids计算模型,无需考虑底层实现。
那么大家说,如果我要做减法怎么办
其实就是list().foldLeft(0)(_ - _)
如果我们把这些加减运算抽象成任意操作,就是functor了
那么他们其实都是一种2元操作
F(A,A):A
那么foldLeft的原型就是 foldLeft(Unit)((A,A) => A)
有人要问,这个在实际场景有什么用处,
其实这些形而上的抽象可以应用到任意场景
举个例子
当我们在做一个App的时候,我们要为用户初始化一系列账号
那么我们在
createAccount的时候
有很多的functors,
......
我们把这些操作放到一个List里面
最后,我们要merge这所有的操作的结果,
List(....).map( f => latchMerge(f.result) )
这个createXXX操作的抽象就是
def f = User => Future[Result]
那么大家要问了,Exception怎么办?发生了错误怎么办?
在Functional Language里面,我们捕获异常,不抛出,返回Either。
这个是函数式语言的在分布式计算和移动计算里面的一个小小的抽象和应用,
这是函数式语言的计算模型的一个连载,敬请期待下期关于Monod的讲解。
以上是关于函数式语言的计算模型 - Monoids的主要内容,如果未能解决你的问题,请参考以下文章