- 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/
以下示例是我现实生活中问题的简化版本。它似乎在某种程度上类似于 Retrieving information from DataKinds constrained existential types
我一直在自学类型级编程,并想编写一个简单的自然数加法类型函数。我的第一个版本如下: data Z data S n type One = S Z type Two = S (S Z) type fam
我在让 GHC 在一个应该很明显的地方推断出一个类型时遇到了问题。以下是演示问题的完整片段。 {-# LANGUAGE DataKinds, ScopedTypeVariables, KindSign
假设我有一个货币类型: data Currency = USD | EUR | YEN 和存储 int 的 Money 类型,并由给定的货币参数化(货币被提升为具有 DataKinds 扩展的种类)。
如果我有一个受有限 DataKind 约束的类型 {-# LANGUAGE DataKinds #-} data K = A | B data Ty (a :: K) = Ty { ... } 以及忘
使用 DataKinds,定义如下 data KFoo = TFoo 介绍种类KFoo :: BOX和类型 TFoo :: KFoo .为什么我不能继续定义 data TFoo = CFoo 这样CF
我从Basic Type Level Programming in Haskell学习Haskell的类型编程但是当它引入 DataKinds 扩展时,示例中有些东西似乎令人困惑: {-# LANGU
我有一个 Universe 类型和一个 Worker 类型。 worker 可以改变宇宙。我想要实现的目标是确保宇宙只能由来自该宇宙的 worker (而不是 future 或过去的 worker )
使用高级类型系统的东西。我想要命名 kind 和 a几个生成此类类型的类型构造函数: {-# LANGUAGE DataKinds #-} data Subject = New | Existing
我有一个常见的模式,其中有一个 [*] 类型的类型级列表,并且我想应用 * -> * 类型的类型构造函数> 到列表中的每个元素。例如,我想将类型 '[Int, Double, Integer] 更改为
我有这个代码片段,它使用了大量的 GHC 扩展: {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GA
我正在尝试找到对 DataKinds 扩展的解释,这对我来说是有意义的,因为我只读过 Learn You a Haskell 。是否有一个标准来源对我来说对我所学到的一点点有意义? 编辑:例如 doc
通过最近有关 HaskellDB 的帖子,我有动力再次研究 HList。由于我们现在在 GHC 中有 -XDataKinds,它实际上有一个异构列表的示例,因此我想研究 HList 与 DataKin
假设我有这个: data Animal = Dog | Cat :t Dog Dog :: Animal 很公平。 :k Dog :1:1: Not in scope: type constr
我正在尝试将 GADT 与 DataKinds 一起使用,如下所示 {-# LANGUAGE KindSignatures, DataKinds, GADTs #-} module NewGadt w
给定一个 ADT data K = A | B Bool DataKinds扩展允许我们将其提升为种类和类型/类型构造函数 K :: BOX 'A :: K 'B :: 'Bool -> K 有没有办
尝试使用 TypeLits 对数据类型进行 JSON 反序列化时,我遇到了以下问题: Couldn't match type ‘n’ with ‘2’ ‘n’ is a rigid type
因此,当我在使用 DataKinds 时尝试确定多态返回值的类型时,ghci 给了我一个有趣的错误。我有以下代码: {-# LANGUAGE DataKinds #-} {-# LANGUAGE Ki
我有一些这样的类型: data Currency = USD | EUR deriving (Show, Typeable) data Money :: Currency
所以,我终于找到了一个可以利用新的 DataKinds 的任务。扩展(使用 ghc 7.4.1)。这是Vec我正在使用: data Nat = Z | S Nat deriving (Eq, Show
我是一名优秀的程序员,十分优秀!