Scalaz
文章平均质量分 78
TIGER_XC
一个Scala童鞋
展开
-
SDP(13): Scala.Future - far from completion,绝不能用来做甩手掌柜
在前面几篇关于数据库引擎的讨论里很多的运算函数都返回了scala.Future类型的结果,因为我以为这样就可以很方便的实现了non-blocking效果。无论任何复杂的数据处理操作,只要把它们包在一个Future{...}里扔给系统运算就算完事不理了,马上可以把关注放到编程的其它部分了。在3月17日的深圳scala用户meetup里我做了个关于scala函数式编程的分享,里面我提到现在使用最多...原创 2018-03-21 11:51:58 · 353 阅读 · 0 评论 -
Scalaz(42)- Free :FreeAp-Applicative Style Programming Language
我们在前面花了几期时间讨论Free Monad,那是因为FP既是Monadic programming,Free Monad是FP模式编程的主要方式。对我们来说,Free Monad代表着fp从学术探讨到实际应用的转变,因为我们已经示范了如何用Free Monad的算式算法关注分离模式来实现真正的软件编程。但是美中不足的是用Free Monad只能编写流程式的程序;我们只能一步一步编译这种程序而无法实现并行运算以及在编译之前对程序结果进行原创 2016-06-02 16:25:44 · 591 阅读 · 0 评论 -
Scalaz(39)- Free :a real monadic program
一直感觉FP比较虚,可能太多学术性的东西。不知道如何把这些数学理论在背后支持的一套全新数据类型和数据结构在现实开发中加以使用。直到Free Monad,才真正感觉能用FP方式进行编程了。这次我想跟大家讨论一下用Free Monad来编写一个真正能运行的完整应用程序。当然,这个程序必须具备FP特性,比如函数组合(function composition),纯代码(pure code),延迟副作用(d原创 2016-04-18 11:17:21 · 3100 阅读 · 1 评论 -
Scalaz(41)- Free :IO Monad-Free特定版本的FP语法
我们不断在重申FP强调代码无副作用,这样才能实现纯代码。像通过键盘显示器进行交流、读写文件、数据库等这些IO操作都会产生副作用。那么我们是不是为了实现纯代码而放弃IO操作呢?没有IO的程序就是一段烧CPU的代码,没有任何意义,所以任何类型的程序都必须具备IO功能,而在FP模式中对IO操作有特别的控制方式:具体实现是通过把代码中产生副作用的部分抽离出来延后运算(在所有纯代码运算之后)。scalaz的原创 2016-05-10 18:57:48 · 961 阅读 · 0 评论 -
Scalaz(40)- Free :versioned up,再回顾
在上一篇讨论里我在设计示范例子时遇到了一些麻烦。由于Free Monad可能是一种主流的FP编程规范,所以在进入实质编程之前必须把所有东西都搞清楚。前面遇到的问题主要与scalaz Free的FreeC类型有关系。这个类型主要是针对一些非Functor的F[A]特别设计的。FreeC是Coyoneda[F,A]的Free Monad类型,任何F[A]都可以被转换成Coyoneda[F,A],而Co原创 2016-04-26 12:29:16 · 1117 阅读 · 0 评论 -
Scalaz(36)- Free :实践-Free In Action - 实用体验
在上面几期讨论中我们连续介绍了Free Monad。因为FP是纯函数编程,也既是纯函数的组合集成,要求把纯代码和副作用代码可以分离开来。Free Monad的程序描述(AST)和程序实现(Interpretation)关注分离(separation of concern)模式恰恰能满足FP要求。我们可以用一些代数数据类型(ADT Algebraic Data Type)来模拟功能,再把这些ADT组原创 2016-03-28 11:46:36 · 535 阅读 · 0 评论 -
Scalaz(38)- Free :Coproduct-Monadic语句组合
很多函数式编程爱好者都把FP称为Monadic Programming,意思是用Monad进行编程。我想FP作为一种比较成熟的编程模式,应该有一套比较规范的操作模式吧。因为Free能把任何F[A]升格成Monad,所以Free的算式(AST)、算法(Interpreter)关注分离(separation of concern)应用模式应该可以成为一种规范的FP编程模式。我们在前面的几篇讨论中都涉及原创 2016-04-12 11:14:17 · 2588 阅读 · 0 评论 -
Scalaz(35)- Free :运算-Trampoline,say NO to StackOverflowError
在前面几次讨论中我们介绍了Free是个产生Monad的最基本结构。它的原理是把一段程序(AST)一连串的运算指令(ADT)转化成数据结构存放在内存里,这个过程是个独立的功能描述。然后在独立的运算过程中Interpreter会遍历(traverse)AST结构,读取结构里的运算指令,具体运行指令。这里的重点是把一连串运算结构化(reify)延迟运行,具体实现方式是把Monad的连续运算方法flatM原创 2016-03-25 21:18:43 · 605 阅读 · 0 评论 -
Scalaz(28)- ST Monad :FP方式适用变量
函数式编程模式强调纯代码(pure code),主要实现方式是使用不可变数据结构,目的是函数组合(composability)最终实现函数组件的重复使用。但是,如果我们在一个函数p内部使用了可变量(mutable variables),如果函数的输入参数e是纯代码,那么表达式p(e)同样是纯代码的,因为函数的调用者是无法接触到函数内部申明的这些可变量的。不过,这样的做法会造成函数的臃肿代码,因为在原创 2016-02-29 08:13:06 · 749 阅读 · 1 评论 -
Scalaz(31)- Free :自由数据结构-算式和算法的关注分离
我们可以通过自由数据结构(Free Structure)实现对程序的算式和算法分别考虑。算式(Abstract Syntax Tree, AST)即运算表达式,是对程序目的的描述。算法则是程序的具体运算方式(Interpreter),它赋予了算式意义。下面我们先简单解释yi x原创 2016-03-12 21:30:34 · 516 阅读 · 0 评论 -
Scalaz(34)- Free :算法-Interpretation
我们说过自由数据结构(free structures)是表达数据类型的最简单结构。List[A]是个数据结构,它是生成A类型Monoid的最简单结构,因为我们可以用List的状态cons和Nil来分别代表Monoid的append和zero。Free[S,A]是个代表Monad的最简单数据结构,它可以把任何Functor S升格成Monad。Free的两个结构Suspend,Return分别代表了原创 2016-03-23 09:49:20 · 520 阅读 · 0 评论 -
Scalaz(30)- Free :Natural Tranformation ~> - map higher kinded types for free
当我们需要定义一些对应高阶类型进行相互类型转换的操作函数时,我们发现scala语言并不提供能定义这种函数的支持。举例来说:如果我们希望定义一个函数把对于任何T值的Option[T]转换成List[T]的话,我们可能这样定义:def toList[T](opt: Option[T]): List[T] = opt.toList原创 2016-03-11 14:47:11 · 646 阅读 · 0 评论 -
Scalaz(43)- 总结 :FP就是实用的编程模式
完成了对Free Monad的学习了解后,心头豁然开朗,存在心里对FP的疑虑也一扫而光。之前也抱着跟大多数人一样的主观概念,认为FP只适合学术性探讨、缺乏实际应用、运行效率低,很难发展成现实的软件开发模式。Free Monad的出现恰恰解决我心中的疑问,更正了我对FP的偏见:Free Monad提供了一套在Monad 算法内(在 for-comprehension内)的行令编程(imperativ原创 2016-06-04 13:30:56 · 1334 阅读 · 0 评论 -
Scalaz(44)- concurrency :scalaz Future,尚不完整的多线程类型
scala已经配备了自身的Future类。我们先举些例子来了解scala Future的具体操作:原创 2016-06-15 11:37:52 · 514 阅读 · 0 评论 -
Scalaz(49)- scalaz-stream: 深入了解-Sink/Channel
一个完整的scalar-stream有以下几个部分组成:Source -> Transducer -> Sink,用直白文字来描述就是:“输入 -> 传换 -> 输出”。我们已经在前面几篇讨论中介绍了Source和Transducer的基本情况,这篇讨论我们探讨一下Sink。scalaz-stream最基本的功能就是从Source接收一串元素,经过处理然后输出。毕竟我们从外部获取了数据、处理完毕后原创 2016-07-21 10:25:54 · 478 阅读 · 0 评论 -
Scalaz(56)- scalaz-stream: fs2-安全运算,fs2 resource safety
fs2在处理异常及资源使用安全方面也有比较大的改善。fs2 Stream可以有几种方式自行引发异常:直接以函数式方式用fail来引发异常、在纯代码里隐式引发异常或者在运算中引发异常,举例如下:/函数式val err = Stream(1,2,3) ++ Stream.fail(new Exception("oh,no...")) //> err : fs2.Stream[Nothi原创 2016-08-25 10:50:46 · 631 阅读 · 0 评论 -
Scalaz(53)- scalaz-stream: 程序运算器-application scenario
从上面多篇的讨论中我们了解到scalaz-stream代表一串连续无穷的数据。对这个数据流的处理过程就是一个状态机器(state machine)的状态转变过程。这种模式与我们通常遇到的程序流程很相似:通过程序状态的变化来推进程序进展。传统OOP式编程可能是通过一些全局变量来记录当前程序状态,而FP则是通过函数组合来实现状态转变的。这个FP模式讲起来有些模糊和抽象,但实际上通过我们前面长时间对FP原创 2016-08-12 10:02:50 · 568 阅读 · 0 评论 -
Scalaz(55)- scalaz-stream: fs2-基础介绍,fs2 stream transformation
fs2是scalaz-stream的最新版本,沿用了scalaz-stream被动式(pull model)数据流原理但采用了全新的实现方法。fs2比较scalaz-stream而言具备了:更精简的基础组件(combinator)、更安全的类型、资源使用(type safe, resource safety)、更高的运算效率。由于fs2基本沿用了scalaz-stream的原理,所以我们会在下面的原创 2016-08-24 10:04:42 · 628 阅读 · 0 评论 -
Scalaz(59)- scalaz-stream: fs2-程序并行运算,fs2 running effects in parallel
scalaz-stream-fs2是一种函数式的数据流编程工具。fs2的类型款式是:Stream[F[_],O],F[_]代表一种运算模式,O代表Stream数据元素的类型。实际上F就是一种延迟运算机制:F中间包含的类型如F[A]的A是一个可能会产生副作用的不纯代码(impure code)的运算结果类型,我们必须用F对A运算的延迟机制才能实现编程过程中的函数组合(compositionality原创 2016-08-31 11:34:33 · 1079 阅读 · 0 评论 -
Scalaz(58)- scalaz-stream: fs2-并行运算示范,fs2 parallel processing
从表面上来看,Stream代表一连串无穷数据元素。一连串的意思是元素有固定的排列顺序,所以对元素的运算也必须按照顺序来:完成了前面的运算再跟着进行下一个元素的运算。这样来看,Stream应该不是很好的并行运算工具。但是,fs2所支持的并行运算方式是以完整的Steam为运算单位的:支持多个Stream同时进行运算,如merge。所以fs2使Stream的并行运算成为了可能。原创 2016-08-30 07:59:40 · 1074 阅读 · 0 评论 -
Scalaz(54)- scalaz-stream: 函数式多线程编程模式-Free Streaming Programming Model
长久以来,函数式编程模式都被认为是一种学术研究用或教学实验用的编程模式。直到近几年由于大数据和多核CPU的兴起造成了函数式编程模式在一些实际的大型应用中的出现,这才逐渐改变了人们对函数式编程无用论的观点。通过一段时间对函数式编程方法的学习,我们了解到Free Monad的算式/算法关注分离(separation of concern)可以是一种很实用的函数式编程模式。用Free Monad编写的程原创 2016-08-19 11:31:28 · 649 阅读 · 0 评论 -
Scalaz(57)- scalaz-stream: fs2-多线程编程,fs2 concurrency
fs2的多线程编程模式不但提供了无阻碍I/O(java nio)能力,更为并行运算提供了良好的编程工具。在进入并行运算讨论前我们先示范一下fs2 pipe2对象里的一些Stream合并功能。我们先设计两个帮助函数(helper)来跟踪运算及模拟运算环境: def log[A](prompt: String): Pipe[Task,A,A] = _.evalMap {a => Task原创 2016-08-27 14:13:01 · 688 阅读 · 0 评论 -
Scalaz(52)- scalaz-stream: 并行运算-parallel processing concurrently by merging
如果scalaz-stream真的是一个实用的数据流编程工具库的话,那它应该能处理同时从多个数据源获取数据以及把数据同时送到多个终点(Sink),最重要的是它应该可以实现高度灵活的多线程运算。但是:我们说Process代表了一串可能是无穷的元素。这个一串的意思是多个按序排列的元素。也就是说如果我们有一个Process('原创 2016-08-03 14:44:37 · 687 阅读 · 0 评论 -
Scalaz(26)- Lens: 函数式不可变对象数据操作方式
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:原创 2016-01-30 11:51:53 · 869 阅读 · 0 评论 -
Scalaz(46)- scalaz-stream 基础介绍
scalaz-stream是一个泛函数据流配件库(functional stream combinator library),特别适用于函数式编程。scalar-stream是由一个以上各种状态的Process串联组成。Process在的类型款式如下:sealed trait Process[+F[_], +O]其中F是个高级类,一种算法,O是Process的运算值。Process由一些原创 2016-07-07 17:49:21 · 438 阅读 · 0 评论 -
Scalaz(50)- scalaz-stream: 安全的无穷运算-running infinite stream freely
scalaz-stream支持无穷数据流(infinite stream),这本身是它强大的功能之一,试想有多少系统需要通过无穷运算才能得以实现。这是因为外界的输入是不可预料的,对于系统本身就是无穷的,比如键盘鼠标输入什么时候终止、网站上有多少网页、数据库中还有多少条记录等等。但对无穷数据流的运算又引发了新的挑战。我们知道,fp程序的主要运算方式是递归算法,这是个问题产生的源泉:极容易掉入Stac原创 2016-07-25 13:28:51 · 680 阅读 · 0 评论 -
Scalaz(29)- Free :Coyoneda - Functor for free
很多时候我们会遇到一些高阶类型F[_],但又无法实现它的map函数,也就是虽然形似但F不可能成为Functor。看看下面的例子:trait Interact[A]case class Ask(prompt: String) extends Interact[String]case class Tell(msg: String) extends Interact[Unit]In原创 2016-03-11 07:55:27 · 646 阅读 · 0 评论 -
Scalaz(27)- Inference & Unapply :类型的推导和匹配
经过一段时间的学习演练,用scala进行函数式编程的过程对我来说就好像是着重如何将函数的款式对齐以及如和正确匹配类型。真正是一种全新的体验,有点太偏重学术型了。原创 2016-02-23 21:04:20 · 621 阅读 · 0 评论 -
Scalaz(10)- Monad:就是一种函数式编程模式-a design pattern
Monad typeclass不是一种类型,而是一种程序设计模式(design pattern),是泛函编程中最重要的编程方式,因而很多行内人把FP又称为Monadic Programming。这其中代表的重要性不言而喻。Scalaz是通过Monad typeclass为数据运算的程序提供了一套规范的编程方式,如著名的for-comprehension。而不同类型的Monad实例则会支持不同的程序原创 2015-10-20 06:26:58 · 936 阅读 · 0 评论 -
Scalaz(12)- Monad:再述述flatMap,顺便了解MonadPlus
object keylog { trait KeyLog[+K] { def value: K def keylog: String override def toString = "["+ value + "," + keylog + "]" def concatLog(log: String) = KeyLog(value, log+";"+keylog)原创 2015-11-13 19:05:15 · 1020 阅读 · 0 评论 -
Scalaz(9)- typeclass:checking instance abiding the laws
在前几篇关于Functor和Applilcative typeclass的讨论中我们自定义了一个类型Configure,Configure类型的定义是这样的:case class Configure[+A](get: A)object Configure { implicit val configFunctor = new Functor[Configure] { d原创 2015-10-13 19:53:59 · 705 阅读 · 0 评论 -
Scalaz(8)- typeclass:Monoid and Foldable
Monoid是种最简单的typeclass类型。我们先看看scalaz的typeclass定义:scalaz/Monoid.scalatrait Monoid[F] extends Semigroup[F] { self => //// /** The identity element for `append`. */ def zero: F...Monoid trait原创 2015-10-09 21:36:13 · 570 阅读 · 0 评论 -
Scalaz(5)- typeclass:my typeclass scalaz style-demo
我们在上一篇讨论中介绍了一些基本的由scalaz提供的typeclass。这些基本typeclass主要的作用是通过操作符来保证类型安全,也就是在前期编译时就由compiler来发现错误。在这篇讨论中我希望能按照scalaz的格式设计自己的typeclass并能使之融入scalaz库结构里去。 我们来设计一个NoneZero typeclass。这个NoneZero typeclass能确定原创 2015-09-19 17:13:25 · 458 阅读 · 0 评论 -
Scalaz(4)- typeclass:标准类型-Equal,Order,Show,Enum
Scalaz是由一堆的typeclass组成。每一个typeclass具备自己特殊的功能。用户可以通过随意多态(ad-hoc polymorphism)把这些功能施用在自己定义的类型上。scala这个编程语言借鉴了纯函数编程语言Haskell的许多概念。typeclass这个名字就是从Haskell里引用过来的。只不过在Haskell里用的名称是type class两个分开的字。因为scala是个原创 2015-09-18 22:13:29 · 749 阅读 · 0 评论 -
Scalaz(7)- typeclass:Applicative-idomatic function application
Applicative,正如它的名称所示,就是FP模式的函数施用(function application)。我们在前面的讨论中不断提到FP模式的操作一般都在管道里进行的,因为FP的变量表达形式是这样的:F[A],即变量A是包嵌在F结构里的。Scalaz的Applicative typeclass提供了各种类型的函数施用(function application)和升格(lifting)方法。与其原创 2015-10-05 11:47:52 · 600 阅读 · 0 评论 -
Scalaz(1)- 基础篇:隐式转换解析策略-Implicit resolution
在正式进入scalaz讨论前我们需要理顺一些基础的scalaz结构组成概念和技巧。scalaz是由即兴多态(ad-hoc polymorphism)类型(typeclass)组成。scalaz typeclass在scala中的应用有赖于scala compiler的一项特别功能:隐式转换(implicit conversion),使程序表述更精简。由于隐式转换是一项compiler功能,在程序编原创 2015-09-06 15:44:39 · 788 阅读 · 0 评论 -
Scalaz(6)- typeclass:Functor-just map
Functor是范畴学(Category theory)里的概念。不过无须担心,我们在scala FP编程里并不需要先掌握范畴学知识的。在scalaz里,Functor就是一个普通的typeclass,具备map over特性。我的理解中,Functor的主要用途是在FP过程中更新包嵌在容器(高阶类)F[T]中元素T值。典型例子如:List[String], Option[Int]等。我们曾经介绍原创 2015-09-26 12:38:27 · 634 阅读 · 0 评论 -
Scalaz(3)- 基础篇:函数概括化-Generalizing Functions
Scalaz是个通用的函数式编程组件库。它提供的类型、函数组件都必须具有高度的概括性才能同时支持不同数据类型的操作。可以说,scalaz提供了一整套所有编程人员都需要的具有高度概括性的通用函数,它是通过随意多态(ad-hoc polymorphism)来帮助用户使用这些函数的。随意多态就是trait+implicit parameters+implicit conversions。简单的说就是sc原创 2015-09-09 20:53:20 · 748 阅读 · 0 评论 -
Scalaz(0) - 写在前面
面向对象编程范畴(OOP)从80年代C++到90年代java的兴起已经经历了几十年的高潮,是不是已经发展到了尽头,该是函数式编程(FP)开始兴旺发达的时候了吧。这样说似乎心眼儿有点坏,可能会得罪当今大多数的编程人员。不过计算机硬件技术的发展往往会催生新的编程技术,这倒是无可反驳的现象。世界当下计算机行业中大数据、电子商务、多核CPU,高并发网络的普及使得C++,java这些OOP范畴的编程语言显得原创 2015-09-02 17:35:26 · 591 阅读 · 0 评论 -
Scalaz(11)- Monad:你存在的意义
前面提到了scalaz是个函数式编程(FP)工具库。它提供了许多新的数据类型、拓展的标准类型及完整的一套typeclass来支持scala语言的函数式编程模式。我们知道:对于任何类型,我们只需要实现这个类型的typeclass实例就可以在对这个类型施用所对应typeclass提供的所有组件函数了(combinator)。突然之间我们的焦点好像都放在了如何获取typeclass实例上了,从而忽略了详原创 2015-10-28 13:46:16 · 648 阅读 · 0 评论