Scalaz 是一个 Scala 库用于函数编程。提供很多纯函数数据结构,定义了一组函数式类,例如 Functor 和 Monad 等。
示例代码:
import scalaz._ import std.option._, std.list._ // functions and type class instances for Option and List scala> Apply[Option].apply2(some(1), some(2))((a, b) => a + b) res0: Option[Int] = Some(3) scala> Traverse[List].traverse(List(1, 2, 3))(i => some(i)) res1: Option[List[Int]] = Some(List(1, 2, 3))
scalaz使用 你们中的大多数人可能都听说过一本很棒的Javascript书:Javascript的好部分。 出于同样的考虑,我想展示一些Scalaz的东西,这些东西在日常项目中非常有用,而不必深入研究Scalaz的(至少对我来说)可怕的内部工作原理。 在第一部分中,我们将深入探讨许多有用的类型类。 在以后的部分中,我们将介绍诸如Monad Transformers,Free monad,Val
从上面多篇的讨论中我们了解到scalaz-stream代表一串连续无穷的数据或者程序。对这个数据流的处理过程就是一个状态机器(state machine)的状态转变过程。这种模式与我们通常遇到的程序流程很相似:通过程序状态的变化来推进程序进展。传统OOP式编程可能是通过一些全局变量来记录当前程序状态,而FP则是通过函数组合来实现状态转变的。这个FP模式讲起来有些模糊和抽象,但实际上通过我们
scalaz使用 在“ Scalaz日常使用功能”的第二篇文章中,我们将探讨Monad变压器和Reader monad的主题。让我们从Monad变压器开始。 当您不得不处理嵌套的Monad时,Monad变压器会派上用场,这种情况经常发生。 例如,当您必须使用嵌套的Future [Option]或Future [Either]时,您的理解很快就会变得不可读,因为您必须明确处理Option的None和
scalaz使用 Scalaz-Camel是一个新项目,它提供了Camel现有Java DSL和Scala DSL的替代DSL,但是Scalaz-Camel与现有DSL相比有什么优势? JAXenter与Talend软件架构师和Scalaz-Camel所有者Martin Krasser进行了交谈。 JAXenter:什么是scalaz-camel项目? Martin Krasser: scalaz
上节我们讨论了Zipper-串形不可变集合(immutable sequential collection)游标,在串形集合中左右游走及元素维护操作。这篇我们谈谈Tree。在电子商务应用中对于xml,json等格式文件的处理要求非常之普遍,scalaz提供了Tree数据类型及相关的游览及操作函数能更方便高效的处理xml,json文件及系统目录这些树形结构数据的相关编程。scalaz Tree的
scalaz-stream是一个泛函数据流配件库(functional stream combinator library),特别适用于函数式编程。scalar-stream是由一个以上各种状态的Process串联组成。stream代表一连串的元素,可能是自动产生或者由外部的源头输入,如:一连串鼠标位置;文件中的文字行;数据库记录;又或者一连串的HTTP请求等。Process就是strea
一个完整的scalaz-stream有以下几个部分组成:Source -> Transducer -> Sink,用直白文字来描述就是:“输入 -> 传换 -> 输出”。我们已经在前面几篇讨论中介绍了Source和Transducer的基本情况,这篇讨论我们探讨一下Sink。scalaz-stream最基本的功能就是从Source接收一串元素,经过处理然后输出。毕竟我们从外部获取了数据、处理
Monoid是种最简单的typeclass类型。我们先看看scalaz的Monoid typeclass定义:scalaz/Monoid.scala trait Monoid[F] extends Semigroup[F] { self => /** The identity element for `append`. */ def zero: F ... Monoid trai
在上一篇讨论里我在设计示范例子时遇到了一些麻烦。由于Free Monad可能是一种主流的FP编程规范,所以在进入实质编程之前必须把所有东西都搞清楚。前面遇到的问题主要与scalaz Free的FreeC类型有关系。这个类型主要是针对一些非Functor的F[A]特别设计的。FreeC是Coyoneda[F,A]的Free Monad类型,任何F[A]都可以被转换成Coyoneda[F,A],
长久以来,函数式编程模式都被认为是一种学术研究用或教学实验用的编程模式。直到近几年由于大数据和多核CPU的兴起造成了函数式编程模式在一些实际大型应用中的出现,这才逐渐改变了人们对函数式编程无用论的观点。通过一段时间对函数式编程方法的学习,我们了解到Free Monad的算式/算法关注分离(separation of concern)可以是一种很实用的函数式编程模式。用Free Monad编写
Applicative,正如它的名称所示,就是FP模式的函数施用(function application)。我们在前面的讨论中不断提到FP模式的操作一般都在管道里进行的,因为FP的变量表达形式是这样的:F[A],即变量A是包嵌在F结构里的。Scalaz的Applicative typeclass提供了各种类型的函数施用(function application)和升格(lifting)方
我们经常提到函数式编程就是F[T]。这个F可以被视为一种运算模式。我们是在F运算模式的壳子内对T进行计算。理论上来讲,函数式程序的运行状态也应该是在这个运算模式壳子内的,也是在F[]内更新的。那么我们就应该像函数式运算T值一样,也有一套函数式更新程序状态的方法。之前我们介绍了Writer Monad。Writer也是在F[]内维护Log的,可以说是一种状态维护方式。但Writer的Log是一种
Functor是范畴学(Category theory)里的概念。不过无须担心,我们在scala FP编程里并不需要先掌握范畴学知识的。在scalaz里,Functor就是一个普通的typeclass,具备map over特性。我的理解中,Functor的主要用途是在FP过程中更新包嵌在容器(高阶类)F[T]中元素T值。典型例子如:List[String], Option[Int]等。我们曾经
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
前面提到了scalaz是个函数式编程(FP)工具库。它提供了许多新的数据类型、拓展的标准类型及完整的一套typeclass来支持scala语言的函数式编程模式。我们知道:对于任何类型,我们只需要实现这个类型的typeclass实例就可以在对这个类型施用所对应typeclass提供的所有组件函数了(combinator)。突然之间我们的焦点好像都放在了如何获取typeclass实例上了,从而
在以前的博文中我们介绍了Slick,它是一种FRM(Functional Relation Mapper)。有别于ORM,FRM的特点是函数式的语法可以支持灵活的对象组合(Query Composition)实现大规模的代码重复利用,但同时这些特点又影响了编程人员群体对FRM的接受程度,阻碍了FRM成为广为流行的一种数据库编程方式。所以我们只能从小众心态来探讨如何改善Slick现状,希望通过
在前面几次讨论中我们介绍了Free是个产生Monad的最基本结构。它的原理是把一段程序(AST)一连串的运算指令(ADT)转化成数据结构存放在内存里,这个过程是个独立的功能描述过程。然后另一个独立运算过程的Interpreter会遍历(traverse)AST结构,读取结构里的运算指令,实际运行指令。这里的重点是把一连串运算结构化(reify)延迟运行,具体实现方式是把Monad的连续运算方法f
scalaz使用 在Scalaz上的迷你系列的这篇文章中,我们将介绍Scalaz中可用的几个附加的monad和模式。 再次,我们将研究实用的内容,并避免使用内部细节或Scalaz。 更准确地说,在本文中,我们将研究: Writer monad:在一组操作期间跟踪某种日志记录 State monad:一种简单的方法来跟踪一组计算中的状态 镜头:轻松访问深层嵌套的属性,并使复制案例类更加方便 本系列当
在任何模式的编程过程中都无法避免副作用的产生。我们可以用F[A]这种类型模拟FP的运算指令:A是可能产生副作用的运算,F[_]是个代数数据类型ADT(Algebraic Data Type),可以实现函数组合(functional composition),我们可以不用理会A,先用F[_]来组合形成描述功能的抽象程序AST(Abstract Syntax Tree),对A的运算可以分开另一个过
fs2在处理异常及资源使用安全方面也有比较大的改善。fs2 Stream可以有几种方式自行引发异常:直接以函数式方式用fail来引发异常、在纯代码里隐式引发异常或者在运算中引发异常,举例如下: /函数式 val err = Stream(1,2,3) ++ Stream.fail(new Exception("oh,no...")) //> err : fs2.Stream[No
我们在前面花了几期时间讨论Free Monad,那是因为FP既是Monadic programming,Free Monad是FP模式编程的主要方式。对我们来说,Free Monad代表着fp从学术探讨到实际应用的转变,因为我们已经示范了如何用Free Monad的算式算法关注分离模式来实现真正的软件编程。但是美中不足的是用Free Monad只能编写流程式的程序;我们只能一步一步编译这种程序
马上进入新的一年2016了,来点轻松点的内容吧。刚好年底这几天抽空重审了一遍,这时才真正认识到让一个老资格OOP程序猿去编写一段FP程序时会发生什么事情:他会用FP语法和数据类型按照OOP的思维编写程序。其结果就是一段尴尬的代码,让人看得不知怎么去形容,更不用提FP程序的精简高雅了。我在前面博文的示范程序正是落入了这个OOP思维陷阱。 我们先把源代码搬过来看看: package Exercise
Monad Reader就是一种函数的组合。在scalaz里函数(function)本身就是Monad,自然也就是Functor和applicative。我们可以用Monadic方法进行函数组合: import scalaz._ import Scalaz._ object decompose { //两个测试函数 val f = (_: Int) + 3
Monad typeclass不是一种类型,而是一种程序设计模式(design pattern),是泛函编程中最重要的编程概念,因而很多行内人把FP又称为Monadic Programming。这其中透露的Monad重要性则不言而喻。Scalaz是通过Monad typeclass为数据运算的程序提供了一套规范的编程方式,如常见的for-comprehension。而不同类型的Monad实例
我们可以通过自由数据结构(Free Structure)实现对程序的算式和算法分离关注(separation of concern)。算式(Abstract Syntax Tree, AST)即运算表达式,是对程序功能的描述。算法则是程序的具体运算方式(Interpreter),它赋予了算式意义。下面我们先用一个例子简单解释何为算式、算法: 用一个简单的表达式 1+2+3,这个表达式同时包含
在“ Scalaz日常使用功能”的第二篇文章中,我们将探讨Monad变压器和Reader monad的主题。让我们从Monad变压器开始。 当您不得不处理嵌套的Monad时,Monad变压器会派上用场,这种情况经常发生。 例如,当您必须使用嵌套的Future [Option]或Future [Either]时,您的理解很快就会变得不可读,因为您必须明确处理Option的None和Some情况以及S
你们中的大多数人都可能听说过一本很棒的Javascript书:Javascript的精髓。 出于同样的考虑,我想展示一些Scalaz的东西,这些东西在日常项目中确实非常有用,而不必深入(至少对我来说)Scalaz令人恐惧的内部工作原理。 在第一部分中,我们将深入探讨许多有用的类型类。 在以后的部分中,我们将介绍诸如Monad Transformers,Free monad,Validation等内
我正在为Packt写一本新书,该书展示了如何使用各种Scala框架创建REST服务。 对于这本书,我正在研究以下框架列表:Finch,未过滤,Scalatra,Spray和Akka-HTTP(反应流)。 在撰写有关Finch和Unfiltered的章节时,我真的很喜欢这两个框架处理验证的方式。 它们都使用可组合的验证器,这些验证器使您可以创建易于使用的验证链,从而收集所有验证错误。 在本文中,我将
我们可以用Monad Reader来实现依赖注入(dependency injection DI or IOC)功能。Scala界中比较常用的不附加任何Framework的依赖注入方式可以说是Cake Pattern了。现在通过Monad Reader可以实现同样功能,两者对比优点各有千秋。所谓依赖注入是指在编程时使用了某个未知实现细节的对象,但依赖注入确保这个对象在这段程序运行时已经实例化。这
函数式编程 -> 函数响应式编程 现在大家已经了解我们是如何运用函数式编程来操作序列的。其实我们可以把这种操作序列的方式再升华一下。例如,你可以把一个按钮的点击事件看作是一个序列: // 假设用户在进入页面到离开页面期间,总共点击按钮 3 次 // 按钮点击序列 let taps: Array<Void> = [(), (), ()] // 每次点击后弹出提示框 taps.forEach {
Python 提供了一个 functools 的模块,该模块为高阶函数提供支持,partial 就是其中的一个函数,该函数的形式如下: functools.partial(func[,*args][, **kwargs]) 这里先举个例子,看看它是怎么用的。 假设有如下函数: def multiply(x, y): return x * y 现在,我们想返回某个数的双倍,即: >>> mu
函数式编程(functional programming)是一种编程范式(Programming paradigm),或者说编程模式,比如我们常见的过程式编程是一种编程范式,面向对象编程又是另一种编程范式。 函数式编程的一大特性就是:可以把函数当成变量来使用,比如将函数赋值给其他变量、把函数作为参数传递给其他函数、函数的返回值也可以是一个函数等等。 Python 不是纯函数式编程语言,但它对函数式
函数式编程 面向值(value-oriented )编程有很多优势,特别是用在与函数式编程结构相结合。这种风格强调值的转换(译注:由一个不变的值生成另一个不变的值)而非状态的改变,生成的代码是指称透明的(referentially transparent),提供了更强的不变型(invariants),因此容易实现。Case类(也被翻译为样本类),模式匹配,解构绑定(destructuring bi
函数式编程是一种声明式编程。 First-class function 纯函数 高阶函数
函数式编程可以说是非常古老的编程范式,但是近年来函数式编程越来越受到关注。不管是 Google 力推的 Go, 学术派的 Scala 与 Haskell,还是 lisp 跑在 JVM 上的新方言 Clojure,这些新的函数式编程语言也都越来越受到关注。
什么是函数式编程 到现在我们已经讲了很多了,但还没有真正涉及到函数式编程。 目前所讲的所有特性 - 丰富的数据类型(rich data types), 模式匹配(pattern matching), 类型推导(type inference), 嵌套函数(nested functions) - 可以想象它们都可以在一种”超级C“语言中存在。这些特性当然很酷,它们使得代码简洁易读,减少bug,但是它们
函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。 而函数式编程(请注意多了一个“式”字)——Functional Programming,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算。 我们首先要搞明白计算机(Computer)和计算