使用 DataKinds 扩展时如何导出类型构造函数?

How to export type constructors when using DataKinds extension?

玩高级类型系统的东西。我想命名为 kind 和 a 产生那种类型的几个类型构造函数:

{-# LANGUAGE DataKinds #-}

data Subject = New | Existing

这里,据我了解,我们命名了种类 Subject 和类型构造函数 NewExisting:: Subject。这些类型构造函数不 接受参数(我打算将它们用作幻影类型),它应该大致是 相当于:

{-# LANGUAGE EmptyDataDecls #-}

data New
data Existing

不同的是现在我可以写:

{-# LANGUAGE DataKinds      #-}
{-# LANGUAGE GADTs          #-}
{-# LANGUAGE KindSignatures #-}

-- …

data MyConfig :: Subject -> * -> * where
  MyConfig
    { mcOneThing :: Path t File
    } :: MyConfig k t

这甚至可以编译。令人困惑的是数据类型的声明是 与数据类型声明无法区分,因此这段代码似乎产生 数据类型 Subject 以及命名种类 Subject (?) 这样会更清楚 对我来说,我们可以指定我们在哪个级别上声明事物(种类,和 那么 NewExisting 是类型构造函数;或类型,然后 NewExistingSubject 类型的值构造函数)。我不 通过“推广所有似乎有效的东西”来获得这个设计决策。

现在,我的问题是我无法将 NewExisting 导出为 在其他模块中使用的类型构造函数,例如声明如下内容:

foo :: MyConfig New Dir -> …

同时

foo :: MyConfig Int Dir -> …

应该是恶意的,不应该编译。

以下是我尝试导出它们的方式:

module MyModule
  ( New
  , Existing
  -- …
  )
where

我得到的:

Not in scope type constructor or class ‘New’

Not in scope type constructor or class ‘Existing’

GHC 手册在 section 7.9.3 说要区分“类型和构造函数”,可以使用单引号 ',所以我尝试了:

module MyModule
  ( 'New
  , 'Existing
  -- …
  )
where

…但现在是解析错误。


如何导出 NewExisting 类型的构造函数,以及大多数 重要的是,我现在的理解有什么问题吗?

使用导出构造函数的常用语法:

module MyModule (Subject(..)) where

data Subject = New | Existing

目前,提升和未提升的构造函数是捆绑在一起的,所以我们只能export/import将它们放在一起。

此外,您不需要在 MyModule 中包含 DataKinds,仅在您打算使用提升构造函数的模块中包含。