我有一个简单的数据类型
data Label = LabelK String
声明:
Label
的类型Type
LabelK
类型的数据构造器String -> Label
会被提升为类型:
'Label
'LabelK
的类型构造函数forall {l :: Symbol}. Label l
但是,事实并非如此,我得到了
:kind 'LabelK :: String -> Label
因此,提升的'LabelK
是一个以String
作为输入并给出类型为'Label
的函数(?)。恐怕Haskell无法做到这一点。
我们可以通过
进行验证data Proxy (i :: k) where
ProxyK :: Proxy i
如果我们想建立'LabelK "titi"
类型的见证人
v3 = ProxyK :: Proxy ('LabelK "titi") -- fails
"titi"
作为promotion of Literals的一部分被提升为Symbol
,我们遇到类型错误。
因此,是通过类型级别字符串(也称为Symbol
)参数化的命名类型的唯一方法,就像在文档中一样,将其编写为? :
data Labl (l :: Symbol) =
Get
Get
类似于ProxyK
,并为我们提供了Labl l
类型的值
:t Get :: forall {l :: Symbol}. Labl l
然后
Get :: Labl "x"
消除了我们无法在类型索引LabelK "titi"
上构建代理的需求
PS:在ghci
中,一个人可以使用
:set -fprint-explicit-kinds
:set -fprint-explicit-foralls
(但是由于某种原因我们不能写v6 = Get :: forall {l :: Symbol}. Labl l
吗?)