泛函编程(14)-try to map them all】的更多相关文章

虽然明白泛函编程风格中最重要的就是对一个管子里的元素进行操作.这个管子就是这么一个东西:F[A],我们说F是一个针对元素A的高阶类型,其实F就是一个装载A类型元素的管子,A类型是相对低阶,或者说是基础的类型.泛函编程风格就是在F内部用对付A类的函数对里面的元素进行操作.但在之前现实编程中确总是没能真正体会这种编程模式畅顺的用法:到底应该在哪里用?怎么用?可能内心里还是没能摆脱OOP的思维方式吧.在前面Stream设计章节里,我们采用了封装形式的数据结构设计,把数据结构uncons放进了特质申明里…
在前面的几节讨论里我们终于得出了一个概括又通用的IO Process类型Process[F[_],O].这个类型同时可以代表数据源(Source)和数据终端(Sink).在这节讨论里我们将针对Process[F,O]的特性通过一些应用实例来示范它的组合性(composibility)和由数据源到接收终端IO全过程的功能完整性. 我们已经在前面的讨论中对IO Process的各种函数组合进行了调研和尝试,现在我们先探讨一下数据源设计方案:为了实现资源使用的安全性和IO程序的可组合性,我们必须保证无…
上期我们讨论了IO处理过程:Process[I,O].我们说Process就像电视信号盒子一样有输入端和输出端两头.Process之间可以用一个Process的输出端与另一个Process的输入端连接起来形成一串具备多项数据处理功能的完整IO过程.但合成的IO过程两头输入端则需要接到一个数据源,而另外一端则可能会接到一个数据接收设备如文件.显示屏等.我们在这篇简单地先介绍一下IO数据源Source和IO数据接收端Sink. 我们先用一个独立的数据类型来代表数据源Source进行简单的示范说明,这…
IO处理可以说是计算机技术的核心.不是吗?使用计算机的目的就是希望它对输入数据进行运算后向我们输出计算结果.所谓Stream IO简单来说就是对一串按序相同类型的输入数据进行处理后输出计算结果.输入数据源可能是一串键盘字符.鼠标位置坐标.文件字符行.数据库纪录等.如何实现泛函模式的Stream IO处理则是泛函编程不可或缺的技术. 首先,我们先看一段较熟悉的IO程序: import java.io._ def linesGt4k(fileName: String): IO[Boolean] =…
泛函编程的核心模式就是函数组合(compositionality).实现函数组合的必要条件之一就是参与组合的各方程序都必须是纯代码的(pure code).所谓纯代码就是程序中的所有表达式都必须是Referentially Transparent(RT,等量可替换的),它的意思是:在一段程序p中,所有的表达式e都可以用e的运算结果替代而不影响到p的运算结果,那么e就是RT等量可替换的,也就是说程序p是由纯代码组成的.但如果程序p中包含了一些变量,这些变量的状态就会影响到程序中e的运算结果,那么p…
由于泛函编程非常重视函数组合(function composition),任何带有副作用(side effect)的函数都无法实现函数组合,所以必须把包含外界影响(effectful)副作用不纯代码(impure code)函数中的纯代码部分(pure code)抽离出来形成独立的另一个纯函数.我们通过代码抽离把不纯代码逐步抽离向外推并在程序里形成一个纯代码核心(pure core).这样我们就可以顺利地在这个纯代码核心中实现函数组合.IO Monad就是泛函编程处理副作用代码的一种手段.我们先…
在上节我们介绍了Trampoline.它主要是为了解决堆栈溢出(StackOverflow)错误而设计的.Trampoline类型是一种数据结构,它的设计思路是以heap换stack:对应传统递归算法运行时在堆栈上寄存程序状态,用Trampoline进行递归算法时程序状态是保存在Trampoline的数据结构里的.数据结构是在heap上的,所以可以实现以heap换stack的效果.这种以数据结构代替函数调用来解决问题的方式又为泛函编程提供了更广阔的发展空间. 我们知道,任何涉及IO的运算都会面临…
泛函编程方式其中一个特点就是普遍地使用递归算法,而且有些地方还无法避免使用递归算法.比如说flatMap就是一种推进式的递归算法,没了它就无法使用for-comprehension,那么泛函编程也就无法被称为Monadic Programming了.虽然递归算法能使代码更简洁易明,但同时又以占用堆栈(stack)方式运作.堆栈是软件程序有限资源,所以在使用递归算法对大型数据源进行运算时系统往往会出现StackOverflow错误.如果不想办法解决递归算法带来的StackOverflow问题,泛函…
经过了一段时间的泛函编程讨论,始终没能实实在在的明确到底泛函编程有什么区别和特点:我是指在现实编程的情况下所谓的泛函编程到底如何特别.我们已经习惯了传统的行令式编程(imperative programming),总是先入为主的认为软件编程就是一行接着一行的更改某些变量状态指令:明刀明枪,字里行间目的和方式都很明确.我们就以一步步更改程序状态的方式,一行一行的拼凑指令:这就是典型的行令式编程了. 泛函编程,顾名思义,就是用一个个函数来编程.讲的再深入点就是通过函数组合来更改程序状态.什么意思?为…
经过了一段时间的学习,我们了解了一系列泛函数据类型.我们知道,在所有编程语言中,数据类型是支持软件编程的基础.同样,泛函数据类型Foldable,Monoid,Functor,Applicative,Traversable,Monad也是我们将来进入实际泛函编程的必需.在前面对这些数据类型的探讨中我们发现: 1.Monoid的主要用途是在进行折叠(Foldable)算法时对可折叠结构内元素进行函数施用(function application). 2.Functor可以对任何高阶数据类型F[_]…