【问题标题】:Runtime "type terms" in LiquidHaskell vs. IdrisLiquidHaskell 与 Idris 中的运行时“类型术语”
【发布时间】:2018-12-14 23:14:53
【问题描述】:

我最近一直在玩 LiquidHaskell 和 Idris,我有一个非常具体的问题,我无法在任何地方找到明确的答案。

Idris 是一种依赖类型的语言,在大多数情况下都很棒。但是我读到类型检查期间的某些类型术语可能会从编译时“泄漏”到运行时,即使是强硬的 Idris 也会尽力消除这些术语(这甚至是一个特殊功能......)。但是,这种消除并不完美,有时确实会发生。如果、为什么以及何时发生这种情况并不能从代码中立即明确,有时会影响运行时性能。

我看到人们更喜欢 Haskells 的类型系统,因为它不可能在那里发生。当类型检查完成时,它就完成了。类型被“丢弃”并且在运行时不使用。

LiquidHaskell 的故事是什么?与传统的 Haskell 相比,它大大增强了类型系统的功能。 LiquidHaskell 是否还为某些类型的“星座”注入运行时位,或者(我怀疑)只是在 Haskell 上添加另一层“更好”的类型,不会影响任何形状或形式的运行时。

意思是,如果去掉特殊的 LiquidHaskell 类型注解并使用标准 GHC 编译它,生成的代码是否总是相同的?换句话说:LiquidHaskell 扩展是否仅编译时?

如果是,这似乎是两全其美,还是 LiquidHaskell 在类型系统中的表现力不如 Idris,因此无需运行时术语即可管理?

【问题讨论】:

  • 请注意,在 Idris 中您可以annotate argument to erasure,因此至少编译器会通知您是否无法擦除 to-erased 参数。此外,在 Idris 的继任者 Bloodwen 中:“未绑定的隐式参数总是被删除,因此尝试对一个进行模式匹配是一种类型错误。”将是一种更易于理解的擦除方法。

标签: haskell idris type-systems liquid-haskell


【解决方案1】:

按要求回答您的问题:Liquid Haskell 允许您提供注释,由编译器之外的单独工具验证。代码仍然以完全相同的方式编译。

但是,我对您提出的问题持怀疑态度。可以说,在某些情况下,该类型的某些残基必须在 Haskell 的运行时存活——尤其是在涉及多态递归时。考虑这个函数:

lots :: Show a => Int -> a -> String
lots 0 x = show x
lots n x = lots (n-1) (x,x)

无法静态确定使用show 所涉及的确切类型。从类型派生的某些东西必须在运行时继续存在。在实践中,使用类型类字典很容易做到这一点。理论上重要的细节是在运行时仍然选择类型导向的行为。

【讨论】:

  • 是的,我知道答案的第二部分。类型类是动态调度的首选 Haskells 方法。但我认为这在三个主要方面是不同的。 1) 何时可能发生这种情况总是很清楚的(每次使用类型类方法时)。 2)通常它可以被优化掉(当最终类型已知并且专业化/内联开始时,动态调度就消失了)。 3)这更像是一种语言,而不是类型系统。甚至一些动态类型的语言也具有动态调度...
  • 我必须在这里补充一点,2)在我上面的评论中可能更常适用于 Haskell,然后是其他语言。我们什么时候有一个类型,我们只知道它实现了“显示”但不知道确切的类型。它可以而且确实会发生,但比在语言中发生的频率要低得多,例如爪哇。但也许我在这里错了......
猜你喜欢
  • 2018-01-21
  • 1970-01-01
  • 1970-01-01
  • 2016-10-04
  • 2016-09-18
  • 1970-01-01
  • 2016-04-11
  • 2018-12-18
  • 1970-01-01
相关资源
最近更新 更多