Scala类型系统——高级类类型(higher-kinded types)
高级类类型就是使用其他类型构造成为一个新的类型,因此也称为 类型构造器(type constructors)。它的语法和高阶函数(higher-order functions)相似,高阶函数就是将其它函数作为参数的函数;高级类类型则是将构造类类型作为参数类型。一个高级类类型可以有一个或者多个类型作为参数。在Scala中,你可以使用type关键字声明,如下:
这里定义了一个高级类类型Callback,该类型接收一个类型 T,并构造一个新的类型Function1。类型Callback不是一个完整的类型,直到它实现了参数化。
Function0,Function1,... 表示接收类型个数1,2,3,... ,如Function0[A],Function1[A,B]... ,一共23个FunctionX。用于定义匿名语法,实现语法糖。
高级类类型可以用于创建复杂类型,如M[N[T,X],Y],但可以看作更简单的类型,F[X]。
Higher-kinded types
除了上面说的用关键字type定义的类型外,高级类类型最常见的实现是使用占位符代替。即F[_],在Scala中,占位符 _ 有特别的意义,可以表示任何东西。
User Story
如我们要实现一个sum方法,该方法可以接收任何Scala集合类型,并实现加法处理。我们可能实现的一种方式是,为所有集合类型定义相对应的方法:
但这并不是一个高效的函数实现,我们要对所有集合类型进行抽象,以使得sum方法可以接收任何集合类型。因此,我们要实现高级类类型。
现在,我们分别为不同的类型实现该特质:
现在,我们要为这个抽象的类类型,实现抽象的方法:
它接收所有集合类型,现在我们为其实现具体的实现:
根据这个特质,我们现在可以实现其通用的函数sum,该函数接收三个参数:集合、Foldable特质、Summable特质,如下:
执行这个方法,打印输出:
好了,我们的高级类类型就已经实现了。但是等等,上面这个函数看起来很死板,我为什么要接收三个参数呢,有没有sum(List(1,2,,3)) sum(Array("one", "two", "three"))这样的实现?有!
Scala有个强大的特性就是隐式调用,我们需要实现这个sum函数的隐式调用,修改如下:
上面的写法实际上和下面是同价的:
修改上述sum函数,让其只接收一个参数:
SBT控制台执行上述代码,便可以得到相同的结果。 
Scala的高级类类型很有用,并且用途广泛,下面我们看看一个Java Servlet到Scala Servlet的一个转换框架Scalaz。
Scalaz核心实现
Scalaz的核心部分很简单,该框架的核心就是实现了所有HTTP请求和响应的抽象。即,把所有的HTTP请求抽象为一个Request特质,所有响应也抽象为一个Response特质。我们看看这个抽象实现的核心代码:
没错,这里的Application,对应Java Servlet里面的application,其中IN[]和OUT[]的实现为Request[IN] => Response[OUT],即抽象请求处理后,返回抽象响应。这个方法实现了高级类类型(higher-kinded types),该方法实现了输入到输出的所有转换,这里的f函数为一个高阶函数实现。
通过高级类类型,结合高阶函数,函数组合,并结合相应的隐式转换和语法糖,Scalaz框架便由此诞生了!!
https://my.oschina.net/Barudisshu/blog/690595
Scala类型系统——高级类类型(higher-kinded types)的更多相关文章
- Scalaz(30)- Free :Natural Tranformation ~> - map higher kinded types for free
当我们需要定义一些对应高阶类型进行相互类型转换的操作函数时,我们发现scala语言并不提供能定义这种函数的支持.举例来说:如果我们希望定义一个函数把对于任何T值的Option[T]转换成List[T] ...
- 【Scala类型系统】自身类型(self type)引用
定义 特质能够要求混入它的类扩展自还有一个类型,可是当使用自身类型(self type)的声明来定义特质时(this: ClassName =>).这种特质仅仅能被混入给定类型的子类其中. 如果 ...
- Java中的原始类型(Primitive Types)与引用类型(Reference Values)
Java虚拟机可以处理的类型有两种,一种是原始类型(Primitive Types),一种是引用类型(Reference Types). 与之对应,也存在有原始值(Primitive Values)和 ...
- 反射01 Class类的使用、动态加载类、类类型说明、获取类的信息
0 Java反射机制 反射(Reflection)是 Java 的高级特性之一,是框架实现的基础. 0.1 定义 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对 ...
- Scala 深入浅出实战经典 第63讲:Scala中隐式类代码实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Scala函数---既存类型
语法: Type ::= InfixType ExistentialClauses ExistentialClauses ::= „forSome‟ „{‟ ExistentialDcl {semi ...
- Programming In Scala笔记-第十七章、Scala中的集合类型
本章主要介绍Scala中的集合类型,主要包括:Array, ListBuffer, Arraybuffer, Set, Map和Tuple. 一.序列 序列类型的对象中包含多个按顺序排列好的元素,可以 ...
- Programming In Scala笔记-第十一章、Scala中的类继承关系
本章主要从整体层面了解Scala中的类层级关系. 一.Scala的类层级 在Java中Object类是所有类的最终父类,其他所有类都直接或间接的继承了Object类.在Scala中所有类的最终父类为A ...
- Scala学习(五)---Scala中的类
Scala中的类 摘要: 在本篇中,你将会学习如何用Scala实现类.如果你了解Java或C++中的类,你不会觉得这有多难,并且你会很享受Scala更加精简的表示法带来的便利.本篇的要点包括: 1. ...
随机推荐
- Java基础学习总结(73)——Java最新面试题汇总
1.super()与this()的区别? this():当前类的对象,super父类对象. super():在子类访问父类的成员和行为,必须受类继承规则的约束 而this他代表当前对象,当然所有的资源 ...
- noip模拟赛 同余方程组
分析:这道题一个一个枚举都能有70分...... 前60分可以用中国剩余定理搞一搞.然而并没有枚举分数高......考虑怎么省去不必要的枚举,每次跳都只跳a的倍数,这样对前面的式子没有影响,为了使得这 ...
- B - Oulipo
The French author Georges Perec (1936�C1982) once wrote a book, La disparition, without the letter ' ...
- RDS For MySQL 字符集相关说明
https://help.aliyun.com/knowledge_detail/41706.html?spm=5176.7841698.2.9.F5YjI5 字符序命名规则 字符集相关 MySQL ...
- [转]SQLSERVER一些公用DLL的作用解释
转自:Leo_wlCnBlogs SQLSERVER一些公用DLL的作用解释 如果你的SQLSERVER安装在C盘的话,下面的路径就是相应SQLSERVER版本的公用DLL的存放路径 SQL2005 ...
- Go语言基础介绍
Go是一个开源的编程语言.Go语言被设计成一门应用于搭载Web服务器,存储集群或类似用途的巨型中央服务器的系统编程语言.目前,Go最新发布版本为1.10. Go语言可以运行在Linux.FreeBSD ...
- HDU 5239 上海大都会 D题(线段树+数论)
打表,发现规律是存在一定次数(较小)后,会出现a=(a*a)%p.可以明显地发现本题与线段树有关.设置标记flag,记录本段内的数是否均已a=a*a%p.若是,则不需更新,否则更新有叶子结点,再pus ...
- #定位系统性能瓶颈# sysdig
安装方法: curl -s https://s3.amazonaws.com/download.draios.com/stable/install-sysdig | sudo bash [root@l ...
- android recovery 系统代码分析 -- 选择进入【转】
本文转载自:http://blog.csdn.net/andyhuabing/article/details/9226569 最近做Recovery的规范及操作指导文档,花了一些时间将流程搞清. An ...
- 逻辑回归 C++
#include <iostream>#include <string>#include <fstream>#include <sstream>#inc ...