为什么GHC在脱毒之前会进行类型检查?

时间:2014-07-08 18:35:23

标签: haskell compiler-construction ghc

有没有理由首先运行类型检查器?如果它运行在较小的语法上,那么类型检查器似乎会变得非常简单,特别是因为在当前系统中,每个语法扩展都需要触及类型检查器。这个问题特别适用于箭头语法,其中as described in comments here被称为伪造的类型检查。

我想这样做的一个原因是不会发出提及生成代码的错误,但是在deriving子句未能进行类型检查的情况下已经涵盖了这种情况。 GHC知道代码是生成的。

1 个答案:

答案 0 :(得分:28)

在本书第2卷"开源应用程序架构"中找到的GHC article中有一个关于此问题的部分:

  

类型检查源语言

     

一个有趣的设计决定是   是否应在脱毒前后进行型式检查。该   权衡是这些:

     
      
  • desugaring之前的类型检查意味着类型检查器必须处理   直接使用Haskell非常大的语法,因此类型检查器具有   很多情况需要考虑。如果我们贬低(一种无类型的变体)   核心第一,人们可能希望类型检查器会变得更多   小。

  •   
  • 另一方面,desugaring后的类型检查会   强加一项重要的新义务:这种贬义不会影响   哪些程序是类型正确的。毕竟,desugaring意味着一个   故意丢失信息。可能就是95%的情况   案件没有问题,但这里的任何问题都会迫使一些问题   在Core的设计中妥协以保留一些额外的信息。

  •   
  • 最重要的是,键入检查一个荒谬的程序就可以了   报告与原始程序文本相关的错误要困难得多,   而不是它(有时复杂的)desugared版本。

  •   
     

大多数编译器在desugaring之后键入check,但对于GHC我们做出了相反的选择:   我们键入检查完整的原始Haskell语法,然后desugar   结果。听起来好像添加一个新的句法结构可能是   复杂,但(继法国学校之后)我们已经构建了   类型推理引擎的方式使其变得简单。类型推断是   分为两部分:

     
      
  • 约束生成:遍历源语法树,生成一个   类型约束的集合。此步骤处理完整语法   Haskell,但它是非常简单的代码,并且很容易添加   新病例。

  •   
  • 约束求解:解决聚集的约束。这是   类型推理引擎的微妙之处在哪里,但确实如此   独立于源语言语法,并且对于a来说是相同的   更小或更大的语言。

  •   
     

总的来说,   type-check-before-desugar设计选择已经证明是一个很大的选择   赢得。是的,它为类型检查器添加了代码行,但它们是   简单的线条。它避免了为同一数据提供两个冲突的角色   类型,并使类型推理引擎不那么复杂,而且更容易   修改。此外,GHC的类型错误消息非常好。