在 Nat 上使用 * 作为原语

Using * as a primitive on Nat

我目前正在阅读 Sandy Maguire 的 Thinking with Types,第 2 章涵盖了 术语、类型和种类。其中有一个与用于在 Nats.

上执行算术的类型级原语

以下会话在书中显示有效,但在我的机器上失败:

Prelude> import GHC.TypeLits
Prelude GHC.TypeLits> :set -XDataKinds
Prelude GHC.TypeLits> :set -XTypeOperators
Prelude GHC.TypeLits> :kind! (1 + 17) * 3

<interactive>:1:1: error:
    * Expected kind `* -> Nat -> k0', but `1 + 17' has kind `Nat'
    * In the type `(1 + 17) * 3'

不过,本书中的下一个示例有效:

Prelude GHC.TypeLits> :kind! (128 `Div` 8) ^ 2
(128 `Div` 8) ^ 2 :: Nat
= 256

我怀疑问题与*有关,也表明种类。 Sandy Maguire 写道,这种语法将被弃用,但如果它仍然存在,我可以看到 GHCi 如何认为我的意思是 kind * 而不是类型级 函数*.

我在正确的轨道上吗?如果是的话,是否有一些标志可以用来使示例工作?

I suspect the problem has something to do with * also indicates a kind.

是的,这就是问题所在。它可以通过使用 -XNoStarIsType 扩展来解决,它允许您将 * 视为另一种类型的运算符。

要引用以前称为 * 的类型,您可以导入 Type 形式 Data.Kind。例如Maybe的种类是Type -> TypeStateT的种类是Type -> (Type -> Type) -> Type -> Type.

希望在未来的某个时候 -XNoStarIsType 将成为默认值,我们将始终使用 Type