- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我从Basic Type Level Programming in Haskell学习Haskell的类型编程但是当它引入 DataKinds
扩展时,示例中有些东西似乎令人困惑:
{-# LANGUAGE DataKinds #-}
data Nat = Zero | Succ Nat
现在,Nat
提升为Kind
,没关系。但是 Zero
和 Succ
怎么样?
我尝试从 GHCi 获取一些信息,因此我输入:
:kind Zero
它给出
Zero :: Nat
没关系,Zero
是一种具有 Nat
类型,对吗?我尝试:
:type Zero
它仍然给出:
Zero :: Nat
这意味着 Zero
具有 Nat
类型,这是不可能的,因为 Nat
是一种而不是类型,对吧? Nat
既是一种类型又是一种种类吗??
还有一个令人困惑的事情是,上面的博客还提到,当创建 Nat
类型时,有两种新类型:'Zero
和 'Succ
自动创建。当我再次从 GHCi 尝试时:
:kind 'Zero
给出
'Zero :: Nat
和
:type 'Zero
给出
Syntax error on 'Zero
好了,证明了'Zero
是一个类型。但是创建'Zero
和'Succ'
的目的是什么??
最佳答案
在未扩展的 Haskell 中,声明
data A = B
定义了两个新实体,计算和类型级别各一个:
A
的新基本类型(属于 *
类型),以及B
的新基本计算(类型为 A
)。当您打开DataKinds
时,声明
data A = B
现在定义了四个新实体,一个在计算级别,两个在类型级别,一个在种类级别:
A
,'B
(属于 A
类型),A
(属于 *
类型),以及B
(类型为 A
)。这是我们之前的严格超集:旧的 (1) 现在是 (3),旧的 (2) 现在是 (4)。
这些新实体解释了您所描述的以下交互:
:type Zero
Zero :: Nat
:kind 'Zero
'Zero :: Nat
:type 'Zero
Syntax error on 'Zero
我认为它如何解释前两个是很清楚的。它解释了最后一个,因为'Zero
是一个类型级别的东西——你不能要求类型的类型,只能要求计算的类型!
现在,在 Haskell 中,名称出现的每个地方,从周围的语法中都可以清楚地看出该名称是计算级名称、类型级名称还是种类级名称。因此,在类型级别必须在 'B
中包含刻度线有点烦人 - 毕竟,编译器知道我们处于类型级别,因此不能引用未提升的计算级别 B
。因此,为了方便起见,在明确的情况下您可以省略勾号。
从现在开始,我将区分“后端”(其中只有上述四个实体并且始终明确)和“表面语法”(您在文件中键入的内容)并传递给 GHC,其中包含歧义,但更方便。使用这个术语,在表面语法中,可以写出以下内容,其含义如下:
Surface syntax Level Back end
Name computation Name
Name type Name if that exists; 'Name otherwise
'Name type 'Name
Name kind Name
---- all other combinations ---- error
这解释了您的第一次互动(也是上面唯一未解释的互动):
:kind Zero
Zero :: Nat
因为 :kind
必须应用于类型级事物,编译器知道表面语法名称 Zero
必须是类型级事物。由于没有类型级后端名称 Zero
,因此它会尝试使用 'Zero
,并获得成功。
怎么可能有歧义呢?好吧,请注意上面我们使用一个声明在类型级别定义了两个 个新实体。为了简单起见,我将等式左侧和右侧的新实体命名为不同的事物。但是让我们看看如果我们稍微调整一下声明会发生什么:
data A = A
我们仍然引入四个新的后端实体:
A
,'A
(类型为A
),A
(类型 *
),并且A
(类型为A
)。哎呀!现在,类型级别同时存在 'A
和 A
。如果您在表面语法中省略勾号,它将使用 (3),而不是 (2) - 并且您可以使用表面语法 'A
显式选择 (2)。
此外,这不必全部通过单个声明来实现。一个声明可能产生打勾版本,另一个声明可能产生非打勾版本;例如
data A = B
data C = A
将引入第一个声明中的类型级后端名称 A
和第二个声明中的类型级后端名称 'A
。
关于haskell - 对 DataKinds 扩展感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53812685/
我正在尝试学习Rust。我正在阅读一本书online,该书实现了unix程序cat。现在,我试图读取作为像cargo run file1.txt file2.txt这样的参数传递的文件的内容,但是程序
我在 GHC 8.0.1 中遇到了一个带有种类索引 (?) GADT 的奇怪情况,其中在类型与种类签名中引入 foralls 会产生不同的类型检查行为。 考虑以下数据类型: {-# LANGUAGE
我正在使用 Perl 5.10 开发应用程序,HTML::Mason和 Apache 2.2。这是我第一次在大型项目中使用 Perl 5.10。我每隔一段时间就会出现奇怪的行为。应用程序因一个非常奇怪
我正在尝试将文件上传到aws中的rust中,因为我使用的是 rusoto_s3 的s3 rust客户端,当这些部分从单个线程发送时,我设法使分段上传代码正常工作不是我想要的,我想上传大文件,并且希望能
我是一名优秀的程序员,十分优秀!