【发布时间】:2016-03-31 01:52:11
【问题描述】:
有没有办法使用'[Foo, Bar, Maybe Quux] 语法构造类型级列表?
可以这样做:
promotedTypeList :: [Q Type] -> Q Type
promotedTypeList [] = promotedNilT
promotedTypeList (t:ts) = [t| $promotedConsT $t $(promotedTypeList ts) |]
但这会导致非常难看的黑线鳕:
type Example = (:) [*] ((:) * Foo ((:) * Bar ((:) * (Maybe Quux) ([] *)))) ([] [*])
编辑:
Haddock / GHC 足够聪明,可以(几乎)打印出用户输入的类型:
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
module T (Foo, Bar) where
type Foo = Int ': Bool ': Char ': '[]
type Bar = '[ Int, Bool, Char ]
显示问题的最小示例是https://gist.github.com/phadej/f92e84a1f03ffb414ab4
【问题讨论】:
-
该语法与该类型完全对应,即
'[X, Y]与X ': Y ': '[]完全相同。前者只是语法糖。列表的打印方式不取决于模板 haskell,而是取决于 GHC 使用的漂亮打印机(或者在本例中为 Haddock)。旧版本的 GHC 会将类型运算符打印为前缀函数,并将包含 kind 参数到类型函数。我不知道您使用的是哪个版本的 Haddock,但我认为这是一个错误 - 不久前它已在 GHC 中修复。 -
@user2407038 GHC 将类型打印为程序员(在本例中为 template-haskell)编写的类型。 IE。我想输入
'[X, Y],但不能使用template-haskell 因此GHC 只能看到X ': Y ': []。没有种类的黑线鳕中的中缀版本已经是一个改进,所以如果有人可以确认它会是这样,比如在 GHC 8.0 中,我会很高兴。 -
"GHC 打印程序员编写的类型" 虽然这通常是正确的,但对于类型级别的列表来说并非如此。定义
type X = '[ Int, Bool, Char ]和type Y = Int ': Bool ': Char ': '[]并询问它们的种类或信息(:kind!或:i),它将使用特殊的列表语法打印它们。事实上你可以写:kind! forall x . (x ': x ': x ': '[])和 ghc 7.8 和 7.10 给我forall (k :: BOX) (x :: k). '[x, x, x]。 -
@user2407038 我不太关心 ghci,但关心 haddock 文档。请参阅问题中的编辑。
-
这似乎是一个黑线鳕问题,在黑线鳕跟踪器中打开了问题:github.com/haskell/haddock/issues/466