有人可以解释或猜测7.9.2 of the GHC user guide部分讨论的数据类型提升限制背后的动机吗?
以下限制适用于促销:
- 我们只推广其种类为
* -> ... -> * -> *
形式的数据类型。特别是,我们不会推广更高级的数据类型,例如data Fix f = In (f (Fix f))
,或类型涉及提升类型的数据类型,例如Vec :: * -> Nat -> *
。
特别是,我对Vec :: * -> Nat -> *
等推广类型的最后一点感兴趣。推广这样的类似似乎很自然。我试图将我的一个库转换成各种幻像类型的特定提升类型,而不是使用类型*
来提供更好的文档等,我很快就遇到了它。
这些编译器限制的原因通常会带着一点思考跳出来,但我没有看到这一点。所以我想知道它是否属于“不需要,所以我们没有建立它”或“那是不可能的/不可判断的/破坏推理。”
答案 0 :(得分:20)
如果您宣传按推广类型索引的类型,则会发生一件有趣的事情。想象一下我们建立
data Nat = Ze | Su Nat
然后
data Vec :: Nat -> * -> * where
VNil :: Vec Ze x
VCons :: x -> Vec n x -> Vec (Su n) x
在幕后,构造函数的内部类型通过约束表示实例化的返回索引,就好像我们已经编写了
data Vec (n :: Nat) (a :: *)
= n ~ Ze => VNil
| forall k. n ~ Su k => VCons a (Vec k a)
现在,如果我们被允许像
那样的话data Elem :: forall n a. a -> Vec n a -> * where
Top :: Elem x (VCons x xs)
Pop :: Elem x xs -> Elem x (VCons y xs)
内部表格的翻译必须是
data Elem (x :: a) (zs :: Vec n a)
= forall (k :: Nat), (xs :: Vec k a). (n ~ Su k, zs ~ VCons x xs) =>
Top
| forall (k :: Nat), (xs :: Vec k s), (y :: a). (n ~ Su k, zs ~ VCons y xs) =>
Pop (Elem x xs)
但请看每种情况下的第二个约束!我们有
zs :: Vec n a
但
VCons x xs, VCons y xs :: Vec (Su k) a
但是在系统FC中如此定义,等式约束必须在两侧都有相同类型的类型,所以这个例子并不是一个小问题。
一个修复是使用第一个约束的证据来修复第二个约束,但是我们需要依赖约束
(q1 :: n ~ Su k, zs |> q1 ~ VCons x xs)
另一个解决办法就是允许异构方程式,就像我十五年前在依赖型理论中所做的那样。事物之间不可避免地存在方程式,它们的种类在语法上是不相等的。
这是目前受欢迎的后一种计划。据我了解,您提到的政策被采纳为持有立场,直到具有异质平等的核心语言(由Weirich及其同事提出)的设计已经成熟到实施。我们生活在有趣的时代。
答案 1 :(得分:4)
这可能源于GHC没有任何特别丰富的“种类”概念,种类是种类,所以
values : type : kind : sort : ...
请注意,虽然我们有一个非常错综复杂的数据种类系统,但所有种类仍然推广到非常简单的种类。提升像Nat
这样的种类需要有多个排序类型/构造函数,而促销Fix
需要更高的排序类型,这在原始排序系统中也没有涉及。
这不是技术障碍,像Coq或Agda这样的语言(依赖类型语言)拥有完整的无限堆栈,但GHC最近才成长为一种类型的系统。它还没有实现任何复杂的排序系统,也许将来我们会得到一个。