高级类类型就是使用其他类型构造成为一个新的类型,因此也称为 类型构造器(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)的更多相关文章

  1. Scalaz(30)- Free :Natural Tranformation ~> - map higher kinded types for free

    当我们需要定义一些对应高阶类型进行相互类型转换的操作函数时,我们发现scala语言并不提供能定义这种函数的支持.举例来说:如果我们希望定义一个函数把对于任何T值的Option[T]转换成List[T] ...

  2. 【Scala类型系统】自身类型(self type)引用

    定义 特质能够要求混入它的类扩展自还有一个类型,可是当使用自身类型(self type)的声明来定义特质时(this: ClassName =>).这种特质仅仅能被混入给定类型的子类其中. 如果 ...

  3. Java中的原始类型(Primitive Types)与引用类型(Reference Values)

    Java虚拟机可以处理的类型有两种,一种是原始类型(Primitive Types),一种是引用类型(Reference Types). 与之对应,也存在有原始值(Primitive Values)和 ...

  4. 反射01 Class类的使用、动态加载类、类类型说明、获取类的信息

    0 Java反射机制 反射(Reflection)是 Java 的高级特性之一,是框架实现的基础. 0.1 定义 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对 ...

  5. Scala 深入浅出实战经典 第63讲:Scala中隐式类代码实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  6. Scala函数---既存类型

    语法: Type ::= InfixType ExistentialClauses ExistentialClauses ::= „forSome‟ „{‟ ExistentialDcl {semi ...

  7. Programming In Scala笔记-第十七章、Scala中的集合类型

    本章主要介绍Scala中的集合类型,主要包括:Array, ListBuffer, Arraybuffer, Set, Map和Tuple. 一.序列 序列类型的对象中包含多个按顺序排列好的元素,可以 ...

  8. Programming In Scala笔记-第十一章、Scala中的类继承关系

    本章主要从整体层面了解Scala中的类层级关系. 一.Scala的类层级 在Java中Object类是所有类的最终父类,其他所有类都直接或间接的继承了Object类.在Scala中所有类的最终父类为A ...

  9. Scala学习(五)---Scala中的类

    Scala中的类 摘要: 在本篇中,你将会学习如何用Scala实现类.如果你了解Java或C++中的类,你不会觉得这有多难,并且你会很享受Scala更加精简的表示法带来的便利.本篇的要点包括: 1. ...

随机推荐

  1. Java基础学习总结(36)——Java注释模板

    代码注释是对代码设计者.代码阅读者以及系统间调用提供了有效的帮助,最大限度的提高团队开发合作效率增强系统的可维护性.我们追求简化,不是为了写注释而写注释. (快速使用请直接看六.七.八) 一.原则: ...

  2. 并行输入\输出控制器之我见(PIO)

    中断信号FIQ及IRQ0到IRQn一般通过PIO控制器复用.但是,由于PIO控制器对于输入无效且中断线(FIQ或IRQ)仅作为输入,因此不必为中断分配I/0线.          电源管理控制器控制P ...

  3. HDU 4362

    方程很简单 p[i][j] = min{dp[i-1][k] + |pos[i-1][k] - pos[i][k]|} + v[i][j]; 循环求值肯定TLE,主要是绝对值不方便.好吧,我真的BI了 ...

  4. 最小堆min_stack

    class MinStack {public: void push(int x) { ele.push(x); if(min.empty()||x<=min.top())    // in or ...

  5. 【Allwinner ClassA20类库分析】4.GPIO类的使用

        从本节起,開始使用ClassA20类库完毕操作外设的功能,请先在https://github.com/tjCFeng/ClassA20下载ClassA20类库. 封装的目的就是简化操作,试想一 ...

  6. CAS 4.0 配置开发手冊

    1    下载 地址http://downloads.jasig.org/ cas-server-4.0.0-release.tar.gz cas-client-3.3.3-release.tar.g ...

  7. job调度时间格式

    */5 * * * * ?---------------每隔5秒执行一次0 */1 * * * ?---------------每隔1分钟执行一次0 0 23 * * ?--------------- ...

  8. Openfire 配置连接SQL SERVER(非默认实例)

    安装好Openfire之后,紧接着进行配置. 连接数据库的时候遇上问题. 打算用我本机上的一个SQL SERVER做为数据库.但是,我本机装了几个SQL SERVER实例,现在我打算使用的是那个非默认 ...

  9. Mongo-JS-导出数据为insert语句

    ======2014-11-14 数据提取======= [query@query-server hurl]$ cat test.sh tlist=`cat ./username.txt`; for ...

  10. vsftpd出现“Response: 500 OOPS: cannot change directory”解决方法(转载)

    vsftpd出现“Response: 500 OOPS: cannot change directory”解决方法   笔者用的Linux发行版本为centos当用FTP客户端连接时,出现如下错误提示 ...