haskell - Haskell 可绑定实体?
问题描述
我看到,在 John Wiley 2004 年的《编程语言设计概念》一书中,有一个可绑定对象的定义:
“可绑定实体是可以绑定到标识符的实体。编程语言在可绑定实体的种类上有所不同:
• C 的可绑定实体是类型、变量和函数过程。
• JAVA 的可绑定实体是值、局部变量、实例和类变量、方法、类和包。
• ADA 的可绑定实体包括类型、值、变量、过程、异常、包和任务。”
我很好奇,Haskell 中有哪些可绑定实体?
解决方案
Haskell 具有三个命名空间,每个命名空间用于运行时计算、类型和模块。
任何表示运行时计算的术语都可以在计算命名空间中命名。data
和newtype
声明在计算命名空间中创建新名称,用于构造其新类型的值,如果使用记录语法,则用于从新类型中选择字段。class
声明在计算命名空间中为其方法创建新名称。
任何单态类型都可以在带有type
声明的类型命名空间中命名(请参阅下面的评论,了解我对本声明中令人困惑的细微之处的预测)。data
和newtype
声明在类型命名空间中创建新名称以构造它们声明的类型。class
声明在类型命名空间中为它们创建的约束创建新名称。
module
声明在模块命名空间中创建新名称。
GHC 扩展了 Haskell,增加了多种新的方法来绑定名称(几乎都在类型命名空间中);对于这种格式,一个完整的列表可能太大了,但该手册非常好,涵盖了所有内容。
现在,到type
. 我预测会出现的一个混淆是:我说只能命名单态类型。但是有人可能会反对我当然可以写,例如
type TypeOfIdMono a = a -> a
id :: TypeOfIdMono a
看起来它已经命名了一个多态类型。我声称 Haskell 使forall
s 隐含的倾向反而混淆了这个问题,这TypeOfId a
实际上是单态的。有了明确的 foralls,这已经写成:
type TypeOfIdMono a = a -> a
id :: forall a. TypeOfIdMono a
那就是:我们实际上并没有id
在这里命名 s 的类型,而是只对a
s 进行操作的单态函数的类型。id
另外说调用者可以选择a
——也就是说,函数是多态的。比较这个声明,它在标准 Haskell 中是不允许的(尽管可以通过 GHC 扩展获得,如上所述):
type TypeOfIdPoly = forall a. a -> a
id :: TypeOfIdPoly
在这里,我们确实命名了一个多态类型。
简而言之:可以而且应该区分三个正交概念:“参数化类型”(例如TypeOfIdMono
,它需要一个额外的参数)、提到类型变量的类型(例如TypeOfIdMono a
)和多态类型(例如TypeOfIdPoly
),它们必须具有forall
.
推荐阅读
- javascript - 在另一个函数完成后运行一个函数
- javascript - Javascript 整理数据
- apache-camel - Apache Camel 文件组件使用不同的目录
- amazon-web-services - 如何从 shell 脚本检查给定的 Amazon S3 密钥是否存在
- reactjs - 反应本机嵌套 AsyncStorage 调用未呈现
- java - 在摩尔斯电码java上使用maven测试时出现错误代码
- c# - CodeEffects RuleEditor 中的小数不被识别为数值
- nginx - 使用 cookie 的 nginx 入口控制器会话亲和性不起作用
- c# - 如何使用 Selenium C# Chromedriver 设置自定义 http 引用标头?
- javascript - FabricJs 画布事件回调正在使用旧的反应功能组件的道具