[英]What exactly are GHC type coercions?
我一直在寻找haskell的核心语言,以了解其工作原理。 我在互联网搜索过程中发现的一项功能是强制类型输入。 我知道它们用于实现GADT,但是我对此了解不多。 尽管我对系统F有相当的了解,但我在网上找到的所有描述对我来说都是相当高的水平。 有人能以一种可以理解的方式向我解释类型强制吗?
基本上,Haskell通过评估这种简单的核心语言来进行编译。 为了保持简单,通常不希望在语言中直接添加GADT或类型类之类的结构,因此,它们会在编译器的最前端被编译成由以下代码提供的更简单但更通用(且冗长)的结构核心。 还要记住,Core是类型化的,因此我们必须确保可以以类型化的方式对所有这些东西进行编码,这是非常复杂的事情。
为了对GADT进行编码,他们使用存在性和强制性将其精化为普通数据类型。 基本思想是强制是带有等式的类型,写t ~ t'
。 这种类型旨在证明有证据表明,即使我们可能不知道, t
和t'
在幕后都是相同的类型。 它们像其他类型一样被传递,因此在处理方式上没有什么特别的。 还有一组类型构造函数,用于处理这些类型,以构造有关相等性的少量证据,例如sym :: t ~ t' -> t' ~ t
。 最后,还有在这需要的类型的一个术语,术语水平的操作者t
和类型的一种t ~ t'
和被分类为类型术语t'
。 例如cast e T :: t'
但该术语的行为与e
相同。 我们只是使用了证明t'
和t
相同来强制e
使类型检查器满意的证明。
这是基本思想
cast
在使用这些证据术语水平 还要注意,通过将证明隔离到类型级别,它们将最终不会产生运行时成本,因为类型将被删除。
我认为在所有这方面都很好的参考是带有类型相等强制的System F,但是SPJ的所有出版物当然都可以提供帮助。
@jozefg应该得到答案,但这是GADT拒绝存在量化的示例。 还不是Core,而是朝它迈出的一步。
data Foo :: * -> * where
Bar :: Int -> Foo Int
Oink :: b -> c -> d -> Foo (f b)
通过
data Foo a where
Bar :: (a ~ Int) => Int -> Foo a
Oink :: (a ~ f b) => b -> c -> d -> Foo a
至
data Foo a
= (a ~ Int) => Bar Int
| forall b c d f. (a ~ f b) => Oink b c d
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.