You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GHC2024中ADTs与GADTs的语法及定义差异问询

Haskell数据类型声明语法疑问(ADT/GADT与Kind标注)

我对数据类型声明的细节理解不够透彻,在多种定义方式中感到困惑:是否该用GADT语法?是否需要写出类型构造器的kind签名或其类型参数的kind?

下面的示例让我产生了**这些语法到底有何差异?**的疑问:

一篇singletons教程里的带幻影类型参数的数据类型声明:

data Door (s :: DoorState) = UnsafeMkDoor { doorMaterial :: String }

之后又给出了GADT语法的替代写法:

data Door :: DoorState -> Type where
    UnsafeMkDoor :: { doorMaterial :: String } -> Door s

我目前能理解的是这两种形式都表达了:

  • Door是Type构造器
    • 后者通过-> Type显式声明了这一点
    • 前者则是通过构造器能生成属于Type的项,间接体现这一点
  • Door是一元类型构造器,接受一个DoorState kind的类型参数

但我还写出了这种介于两者之间的形式:

data Door (s :: DoorState) where
  UnsafeMkDoor :: { doorMaterial :: String } -> Door s

这种写法用了GADT语法的where,但又像非GADT语法那样显式指定了Door的类型参数s并标注了:: DoorState。

关键疑问是:这里的s和前两种写法里的s是否是同一指代?这种定义Door的方式和前两种有没有本质差异?

我知道查看ADTs和GADTs的语法规范会有帮助,但不确定该找哪里。之前了解到Haskell2010报告是规范,但上面这些代码依赖的扩展都超出了Haskell2010的范围,所以想知道GHC2024中ADTs与GADTs的语法细节。

内容的提问来源于stack exchange,提问作者Enlico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 10:03:20