简体   繁体   English

在 Haskell 的 -XDataKinds 中使用列表类型

[英]using list types with Haskell's -XDataKinds

I was using a return type in a function (using package haskell-src-exts ):我在函数中使用了返回类型(使用包haskell-src-exts ):

import Language.Haskell.Exts.Syntax (Exp(..))
import Language.Haskell.Exts.SrcLoc (SrcSpanInfo(..))
:k Exp SrcSpanInfo
Exp SrcSpanInfo :: *

That's a type.那是一种。 So far so good.到现在为止还挺好。

But now I wanted to type it better:但现在我想更好地输入它:

:set -XDataKinds
> :k 'List
'List :: l -> [Exp l] -> Exp l

So, this thing wants some more stuff.所以,这东西想要更多的东西。 Fine, I can do that.很好,我可以做到。

> :k 'List SrcSpanInfo 
'List SrcSpanInfo :: [Exp *] -> Exp *

One step off.一步之遥。 Okay.好的。

> :k 'List SrcSpanInfo [Exp SrcSpanInfo]

<interactive>:1:19: error:
    • Expected kind ‘[Exp *]’, but ‘[Exp SrcSpanInfo]’ has kind ‘*’
    • In the second argument of ‘ 'List’, namely ‘[Exp SrcSpanInfo]’
      In the type ‘ 'List SrcSpanInfo [Exp SrcSpanInfo]’

At this point, I'm feeling quite confused.在这一点上,我感到很困惑。 To me it feels like what I gave it was definitely pretty much what it asked for.对我来说,感觉就像我给它的东西绝对是它所要求的。 What exactly does it mean?究竟是什么意思?

From the comments, it suddenly occurred to me that you're probably not actually looking for the lifted types (ie kinds), but rather for regular types.从评论中,我突然想到您实际上可能不是在寻找提升类型(即种类),而是在寻找常规类型。

From the comments (specifically: "... desired kind * ...") it seems like you're just looking to construct a value of type Exp SrcSpanInfo (and indeed, these types are not actually intended for kind-level usage).从评论(特别是:“...所需种类* ...”)看来,您似乎只是想构造一个Exp SrcSpanInfo类型的值(实际上,这些类型实际上并不用于种类级别的使用) .

To do that, just apply parameters to the constructor:为此,只需将参数应用于构造函数:

> span = noInfoSpan $ mkSrcSpan noLoc noLoc
> :t span
span :: SrcSpanInfo
> list = List span []
> :t list
list :: Exp SrcSpanInfo

Original answer原答案

The expression [Exp SrcSpanInfo] does not denote " a type-level list of types with a single element Exp SrcSpanInfo ", but rather denotes " a single type that is a list of elements of type Exp SrcSpanInfo ", similar to [Int] or [String] .表达式[Exp SrcSpanInfo]并不表示“具有单个元素Exp SrcSpanInfo的类型级别列表”,而是表示“一个类型为Exp SrcSpanInfo类型元素列表的单一类型”,类似于[Int][String]

The compiler has no way of distinguishing the former from the latter, so it defaults to the older, more standard interpretation.编译器无法区分前者和后者,因此它默认使用较旧的、更标准的解释。

In order to make it see a type-level list, it must be quoted with a single quote, just like you did with 'List .为了让它看到一个类型级别的列表,它必须用单引号引用,就像你对'List所做的那样。

Further, Exp is a type, but when used in a kind signature, it's elevated to a kind.此外, Exp是一种类型,但是当用于种类签名时,它被提升为一种类型。 In order to construct a type of kind Exp * , you have to use one of its constructors .为了构造一种Exp *类型,您必须使用它的一个构造函数 I will use the List constructor, because it was the easiest to instantiate:我将使用List构造函数,因为它最容易实例化:

> :k 'List SrcSpanInfo '[ 'List SrcSpanInfo '[] ]

[a] is the type of lists. [a]是列表的类型。 To construct a (promoted) list, write '[a] :要构建(提升)列表,请编写'[a]

:k 'List SrcSpanInfo '[ 'List Int '[] ]

Applying 'List to a type, such as SrcSpanInfo , is probably not what you want either (hopefully my example applying it also to an Int tells that something is off).'List应用于类型,例如SrcSpanInfo ,可能也不是您想要的(希望我的示例也将它应用于Int表明某些事情已关闭)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM