避免类型级自然的类约束

时间:2017-01-10 04:31:38

标签: haskell type-level-computation

我正在使用GHC.TypeLits模块中的Nat类型,它确实说程序员接口应该在一个单独的库中定义。在任何情况下,GHC.TypeLits都有一个类KnownNat,其类函数natVal可将编译时间Nat转换为运行时Integer。还有一个类型函数(+),它增加了编译时间Nat

问题在于给定(KnownNat n1, KnownNat n2),GHC无法导出KnownNat (n1 + n2)

每当我添加类型级别自然时,都会导致需要添加的约束爆炸。

另一种选择是自己定义自然数字:

data Nat = Zero | Succ Nat

或者使用像type-natural这样的库。但是如果不使用内置于GHC中的Nats似乎很愚蠢,这也允许您很好地使用类型中的文字数字(即01)而不必定义:

N0 = Zero
N1 = Succ N0
etc...

是否存在围绕此问题的GHC KnownNat限制在整个地方都需要?或者我应该忽略问题的GHC.TypeLits模块?

1 个答案:

答案 0 :(得分:10)

此GHC类型检查器插件正是这样做的(从已经可用的其他约束中获取“复杂”KnownNat约束):https://hackage.haskell.org/package/ghc-typelits-knownnat

如果“类型检查器插件”听起来有点吓人(它最初对我有用),它实际上非常简单易用。只需将其作为依赖项添加到您的包文件(或cabal安装它),就像任何其他包一样,然后添加:

{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}

到源文件的开头(很像LANGUAGE pragma),或者在包文件中全局添加它作为选项。

同一作者还有另一个插件,对于使用类型Nats非常有用:https://hackage.haskell.org/package/ghc-typelits-natnormalise。这个能够推断GHC本身所放弃的Nat类型表达式的相等性:像n + (m + 1) ~ (n + 1) + m这样的东西,当GHC试图证明“预期”和“实际”类型匹配时,它会一直出现。< / p>