您在Haskell中找到了更高级别类型的用途?

时间:2009-09-25 10:09:55

标签: haskell types polymorphism type-systems higher-rank-types

更高级别的类型看起来非常有趣。来自Haskell wikibook来自这个例子:

foo :: (forall a. a -> a) -> (Char,Bool)
foo f = (f 'c', f True)

现在我们可以在没有编译器爆炸的情况下评估foo id。这个例子在本书中很快被我在其他几个地方看到的真实例子:ST monad和runST。那太酷了。

但是我还没有遇到过这样一种情况:我通过使用更高级别的参数编写自己的函数来解决问题。你呢?您在野外有什么样的rank-2或rank-n多态性?

5 个答案:

答案 0 :(得分:8)

Weirich和Washburnn的“Boxes go Bananas”! (paperslides

这是一个非常原始的,可能稍微不准确的解释它的全部内容:给定一个归纳类型,BGB允许你表示那种类型的函数空间是“积极的” - 它们从不区别于它们的论点。它们最多包含其参数作为其他值的一部分(通常是相同类型)。

Weirich + Washburn使用它来获得-XRankNTypes Haskell中lambda演算的可能 - adequate HOAS表示(有人证明它已经足够了吗?)。

我使用它here(警告:凌乱的代码)转一个

(forall g . GArrow g => g () x -> g () y)

进入

(forall g . GArrow g => g x y)

这是有效的,因为rank-2多态类型不能“检查”其参数的结构 - 它能做的就是将该参数“粘贴”到更大的结构中。一些技巧让我弄清楚粘贴发生的位置,然后我将粘贴点(如果有的话)回到GArrow的输入。

您无法使用Control.Arrow类执行此操作,因为整个Haskell函数空间通过arr“泄漏”到其中。

答案 1 :(得分:7)

查看Darcs source中的withRepoLock等函数。

Darcs支持多种存储库格式,并且通过类型类表示支持。因此,您可以编写通用存储库格式的通用代码。在实际读取磁盘存储库时,您希望通过一些公共代码调度到该代码,该代码确定存储库所处的格式并选择正确的类型类实例化。

答案 2 :(得分:7)

最近有人asked a question here on Stack Overflow可以用更高级别的类型来解决。

另一个应用程序在Scrap Your Boilerplate论文中。

答案 3 :(得分:3)

您可能遇到过排名较高的类型有用但未能实现的问题。例如,在Darcs示例中,他们可以很容易地实现它而没有更高级别的类型。相反,调用者必须确保它们遵守某些函数的先决条件,例如为存储库格式选择正确的函数实例化。

排名较高的类型的优点是它将从程序员到编译器的权利转移到了。使用传统方法,如果Darcs开发人员使用存储库类型出错,结果将是运行时错误或其他损坏的数据。对于排名较高的类型,开发人员在编译时会收到类型错误。

答案 4 :(得分:0)

可以在 Luke Palmer 的 IO-free splittable supply - 他展示了如何 使用简单的唯一值供应可以获得一个纯粹的接口:

runSupply :: (forall a. Eq a => Supply a -> b) -> b