如果scalaz-stream真的是一个实用的数据流编程工具库的话,那它应该能处理同时从多个数据源获取数据以及把数据同时送到多个终点(Sink),最重要的是它应该可以实现高度灵活的多线程运算.但是:我们说Process代表了一串可能是无穷的元素.这个一串的意思是多个按序排列的元素.也就是说如果我们有一个Process(a,b,c),那么我们只能按顺序来进行运算:我们只能在完成了对a的运算后才能运算b.这样也说得过去:它让我们更容易理解scalaz-stream Process的运算过程.面对sc…
外面沙尘滚滚一直向北去了,意识到年关到了,码农们都回乡过年去了,而我却留在这里玩弄“拉链”.不要想歪了,我说的不是裤裆拉链而是scalaz Zipper,一种泛函数据结构游标(cursor).在函数式编程模式里的集合通常是不可变的(immutable collection),我们会发现在FP编程过程中处理不可变集合(immutable collection)数据的方式好像总是缺些什么,比如在集合里左右逐步游动像moveNext,movePrev等等,在一个集合的中间进行添加.更新.删除的功能更是…
Monoid是种最简单的typeclass类型.我们先看看scalaz的Monoid typeclass定义:scalaz/Monoid.scala trait Monoid[F] extends Semigroup[F] { self => //// /** The identity element for `append`. */ def zero: F ... Monoid trait又继承了Semigroup:scalaz/Semigroup.scala trait Semigroup[…
Functor是范畴学(Category theory)里的概念.不过无须担心,我们在scala FP编程里并不需要先掌握范畴学知识的.在scalaz里,Functor就是一个普通的typeclass,具备map over特性.我的理解中,Functor的主要用途是在FP过程中更新包嵌在容器(高阶类)F[T]中元素T值.典型例子如:List[String], Option[Int]等.我们曾经介绍过FP与OOP的其中一项典型区别在于FP会尽量避免中间变量(temp variables).FP的变…
我们在上一节讨论了scalaz Future,我们说它是一个不完善的类型,最起码没有完整的异常处理机制,只能用在构建类库之类的内部环境.如果scalaz在Future类定义中增加异常处理工具的话,用户就会经常遇到Future[Throwable\/A]这样的类型,那么在进行Monadic编程时就必须使用Monad Transformer来匹配类型,程序就会变得不必要的复杂.scalaz的解决方案就是把Future[Throwable\/A]包嵌在Task类里,然后把所有Future都统一升格成T…
scala中的case class是一种特殊的对象:由编译器(compiler)自动生成字段的getter和setter.如下面的例子: case class City(name:String, province: String) case class Address(street: String, zip: String, city: City) case class Person(name: String, age: Int, phone: String, address: Address)…
马上进入新的一年2016了,来点轻松点的内容吧.前面写过一篇关于用Reader实现依赖注入管理的博文(Scalaz(16)- Monad:依赖注入-Dependency Injection By Reader Monad).刚好年底这几天抽空重审了一遍,这时才真正认识到让一个老资格OOP程序猿去编写一段FP程序时会发生什么事情:他会用FP语法和数据类型按照OOP的思维编写程序.其结果就是一段尴尬的代码,让人看得不知怎么去形容,更不用提FP程序的精简高雅了.我在前面博文的示范程序正是落入了这个OO…
scalaz还提供了个type class叫Validation.乍看起来跟\/没什么分别.实际上这个Validation是在\/的基础上增加了Applicative功能,就是实现了ap函数.通过Applicative实例就可以同时运算多个Validation并返回多条异常信息.所以,\/与Validation核心分别就在于Validation可以返回多条异常信息.Validation也是由两种状态组成:Success和Failure,分别与\/的left和right相对应.Failure可以返…
说道FP,我们马上会联想到Monad.我们说过Monad的代表函数flatMap可以把两个运算F[A],F[B]连续起来,这样就可以从程序的意义上形成一种串型的流程(workflow).更直白的讲法是:任何类型只要实现了flatMap就可以用for-comprehension, for{...}yield.在这个for{...}里我们可以好像OOP一样编写程序.这个for就是一种运算模式,它规范了在for{...}里指令的行为.我们正从OOP风格走入FP编程模式,希望有个最基本的FP编程模式使我…
我们经常提到函数式编程就是F[T].这个F可以被视为一种运算模式.我们是在F运算模式的壳子内对T进行计算.理论上来讲,函数式程序的运行状态也应该是在这个运算模式壳子内的,也是在F[]内更新的.那么我们就应该像函数式运算T值一样,也有一套函数式更新程序状态的方法.之前我们介绍了Writer Monad.Writer也是在F[]内维护Log的,可以说是一种状态维护方式.但Writer的Log是一种Monoid类型,只支持Semigroup的a|+|b操作,所以只能实现一种两段Log相加累积这种效果.…