Haskell基本用法

示例

当GADTs启用了扩展,除了常规的数据申报,也可以申报广义代数的数据类型如下:

data DataType a where
    Constr1 :: Int -> a -> Foo a -> DataType a
    Constr2 :: Show a => a -> DataType a
    Constr3 :: DataType Int

GADT声明明确列出了数据类型具有的所有构造函数的类型。与常规数据类型声明不同,构造函数的类型可以是任何最终导致将数据类型应用于某些参数的N元(包括空值)函数。

在这种情况下,我们已经宣布的类型DataType有三种构造函数:Constr1,Constr2和Constr3。

Constr1构造函数与使用常规数据声明声明的构造函数没有什么不同:data DataType a = Constr1 Int a (Foo a) | ...

Constr2但是需要a具有的实例Show,因此在使用构造函数时,实例必须存在。另一方面,当对其进行模式匹配时,作为a的实例这一事实Show就成为了范围,因此您可以编写:

foo :: DataType a -> String
foo val = case val of
    Constr2 x -> show x
    ...

请注意,Show a约束不会出现在函数的类型中,而仅在右侧的代码中可见->。

Constr3具有类型DataType Int,这意味着每当类型的DataType a值为a时Constr3,都知道a ~ Int。该信息也可以通过模式匹配来恢复。