5.3 用抽象类型建立泛型模型(Modeling Generics with Abstract Types)
一种语言里有两套抽象语法体系肯定会让人产生对这种语言复杂性的疑问:能不能就用一种形式化体系来实现?本节当中我们将会展示,函数式的类型抽象机制(也就是泛型)实际上可以通过面向对象的类型抽象机制(也就是抽象类型)来表达。这种表达方式的思路如下所述:
假定一个参数化类型C有一个类型参数t(可以直接推广到多个类型参数的情况),那么这种表达方式有四个关键组成部分:分别是类型自身的定义、类型实例的创建、基类构造子的调用以及这个类的类型实例(type instances)。
1. 类型定义,C的定义可以重写如下:
class C {
type t
/* rest of class */
}
也就是说,C的类型参数可以用其抽象成员来重新定义。如果类型参数有上界或者下界,则可以带到抽象成员的定义上。类型参数的协变性则不带到抽象成员的定义上,参见第4点。
2. 以T为参数创建实例的调用:new C[T]可以写成:
new C{ type t=T }
3. 如果C[T]出现在调用基类构造符的场合,则其子类的定义将会进行如下扩充:
type t = T
4. 每一个C[T]形式的类型定义都被扩充为如下的细化形式:
C { type t = T } 如果t被声明为非协变
C { type t <: T } 如果t被声明为协变
C { type t >: T } 如果t被声明为逆协变
这种表达方式在一种情况下会有问题:命名冲突。这是因为参数的名称成为了类的成员,可能和其他成员冲突,包括其父类的类型参数转化成的成员。这种冲突可以通过重命名解决,例如给每个类型名称指定一个唯一数字标识。
两种抽象模式之间可以转换,对于一种语言还是有价值的,因为可以降低其内在的概念复杂性。例如,Scala的泛型,实际上就是一种语法糖,完全可以被抽象类型替代掉。既然如此,也许会有人问,这种语法糖有没有必要性?或者说为什么不只用抽象类型呢,这样可以使语法本身简化很多。实际上,Scala中引入泛型有两重意义:首先,手工把泛型转化为成为抽象类型表达形式并不那么简单,不仅会丧失语法的简洁性,而且还可能带来前述的命名冲突等问题。其次,泛型和抽象类型在Scala中一般扮演不同的角色,泛型一般用于类型的实例化,而抽象类型主要用于在调用者代码中对相应的抽象类型进行引用。后者主要来自于两个场合:一个是有人需要在客户代码中隐藏相关类型信息,用于构造类似于SML模式的模块系统。另一个是在子类中协变地继承父类的类型,从而获得族多态。
可能有人会问,那么是否可以反过来用泛型来替代抽象类型呢?一些对于两种抽象方式都支持的系统进行的研究[27]证实,这样做要困难得多,至少整个程序都需要重写。不仅如此,如果系统要实现受限多态的话,重写类型上/下界的部分会呈平方级增长[8]。实际上这一点也不奇怪,因为这两种类型体系的理论基础就不同,泛型(不带F-界的)可以用F<:系统来表达[11],而抽象类型则建立在类型依赖的基础之上。后者比前者的表现力更强,例如,带路径依赖类型的vObj演算是可以涵盖F<:的。
分享到:
相关推荐
scala特点 3 数据类型 3 字符串 4 变量 4 标识符 5 操作符 5 块表达式与赋值 5 控制结构 6 函数 8 类(class)和对象(object) 14 抽象类和抽象成员 17 继承与覆盖(override) 18 特质(trait) 19 显式类型转换 20 隐式...
”本教程概述了Scala强大的类型系统及函数式编程功能如何提供一个出色的画布,以处理微服务组合及其产生的问题。我们还将重点讲述模型驱动的开发样式。微服务通常实施一个有界上下文,这是来自域驱动的设计概
内容包括: Scala语言概述、运算符、程序流程控制、数据结构之集合、Map映射、过滤、化简、折叠、扫描、拉链、视图、并行集合、高阶函数、函数柯里化、偏函数、参数推断、控制抽象、Trait、面向对象编程、异常处理、...
java容器源码与Docker的...第四章和第五章将示例Scala WebApp与Jenkins服务器结合在一起。 下一章将提供我们在Amazon Web Service上运行服务的经验。 我们在其他章节中添加了结论和未解决的问题。 作者 作者:MichaelK
RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合。在 Spark 中,对数据的所有操作不外乎创建 RDD、转化已有RDD 以及...
概述 Cats是一个库,为使用功能编程提供了抽象。 这个名字是单词类别的一个好玩的缩写。 Scala支持面向对象和功能编程,这在标准库的混合方法中得到了体现。 猫致力于提供功能性编程抽象是核心,,,和。 Cats的更...
java原始代码添加自动Java程序记录器(用Scala写) 团队成员:Abdullah Aleem和Muhammad Maaz Khan 概述 该项目是一个工具程序,它使用语法正确的Java文件,并使用Eclipse Java抽象语法树解析器来解析,重写和记录...
这些是我在2014年Scala Exchange和2015年阿姆斯特丹ScalaDays上的演讲的幻灯片和代码示例。该演讲是关于使用函数式编程概念设计库代码所涉及的思维过程的入门级讨论。 概述的基本思想过程如下: 定义最小,最简单...
概述 请记住:在下面的链接中,请使用真实的AWS帐户(例如inventale dev沙箱),而不要假冒{9999999} 该项目包含Scala WeatherToParquetJob作业,以使用将数据从样本转换为镶木地板并将其存储到s3存储桶。 代码...
它旨在使扑扑/Dart开发人员可以使用两种最受欢迎的模式和抽象: Either和Option ,主要用于FP语言,例如Scala,Haskell,OCaml,... 安装 支持零安全性的预发行版本 pub上的包链接在pubspec.yaml依赖项中添加 ...
此过程称为构建eDSL(嵌入式领域特定语言)并对其进行解释,并且在功能语言(例如Haskell,Scala,OCaml)中得到了广泛使用。 尽管如此,对于许多JS / TS开发人员来说,这个主题还是一个未知数。 在本研讨会上,我...
概述 本项目的要求是: 一个检测程序,它采用一些 Java 应用程序的语法正确的源代码,并使用 Eclipse Java 抽象语法树 (AST) 解析器将此应用程序解析为 AST 对于每个作用域中的每个表达式和语句,程序将插入一个检测...