数据类型声明中的 a 代表什么?

问题描述

通常在使用类型声明时我们会这样做:

function_name :: Type -> Type

但是在我试图解决的练习中,有以下结构:

function_name :: Type a -> Type a

或在练习中明确表示

alphabet :: DFA a -> Alphabet a
alphabet = undefined

a 代表什么?

解决方法

简答:它是一个类型变量。

在计算层面,我们定义函数的方式是使用变量来引用它们的参数。像这样:

f x = x + 3

这里的 x 是一个变量,它的值会在函数调用时被选择。 Haskell 在其类型子语言中具有类似(但不完全相同...)的机制。例如,您可以编写如下内容:

type F x = (x,Int,x)
type Endo a = a -> a -> a

这里的 x 是第一个变量(第二个是 a),它的值将在使用站点选择。在定义新类型时也可以使用这种机制。 (前两个示例只是为现有类型赋予新名称,但以下示例更多。)最基本的重要示例之一是 Maybe 类型家族:

data Maybe a = Nothing | Just a

= 右边的东西是计算级的,所以你现在可以忽略它们,但是在左边我们声明了一个新的类型家族 Maybe 接受其他类型作为论据。例如,Maybe IntMaybe (Bool,String)Maybe (Endo Char),甚至传入具有 Maybe (x,x) 等变量的表达式都是可能的。

在语法上,类型构造函数(定义为程序文本的一部分并且我们希望编译器查找定义的事物)以大写字母和类型变量(稍后将实例化的事物等)开始'目前没有具体的定义)以小写字母开头。

因此,在您显示的类型签名中:

alphabet :: DFA a -> Alphabet a

我怀疑实际上有两个构造对您来说是新的,而不仅仅是一个:首先,您询问的类型变量 a,其次,类型应用程序的概念,其中我们在类型级别将一种“类函数”类型应用于另一种类型。 (在这个答案之外,人们说“参数化”而不是“类函数”。)

...而且,不管你信不信,甚至有一个类型系统可以确保你不会写这样的东西:

Int a -- Int is not parameterized,so shouldn't be applied to arguments
Int Char -- ditto
Maybe -> String -- Maybe is parameterized,so should be applied to
                -- arguments,but isn't