使用高级类型系统的东西。我想命名 kind 和几个产生这种类型的类型构造函数:
{-# LANGUAGE DataKinds #-}
data Subject = New | Existing
在这里,据我了解,我们命名了 kindSubject
和 type 构造函数
New
,Existing
它们是:: 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
(?)对我来说更清楚的是,我们可以指定我们在哪个级别声明事物(种类,然后New
和Existing
是类型构造函数;或类型,然后New
和Existing
是类型事物的值构造函数Subject
)。我没有通过“推广所有似乎可行的东西”来做出这个设计决定。
现在,我的问题是我无法导出New
并Existing
作为类型构造函数在其他模块中使用,例如声明如下内容:
foo :: MyConfig New Dir -> …
同时在哪里
foo :: MyConfig Int Dir -> …
应该是恶意的,它不应该编译。
这是我尝试导出它们的方式:
module MyModule
( New
, Existing
-- …
)
where
我得到什么:
不在作用域类型构造函数或类'New'中</p>
不在作用域类型构造函数或类“现有”中</p>
GHC 手册
第 7.9.3 节
中说要区分“类型和构造函数”,可以使用单引号'
,所以我尝试了:
module MyModule
( 'New
, 'Existing
-- …
)
where
…但现在这是一个解析错误。
如何导出New
和Existing
键入构造函数,最重要的是,我目前的理解有什么问题吗?