Haskell 为什么可以';t值构造函数在不参数化类型的情况下获取类型变量?

Haskell 为什么可以';t值构造函数在不参数化类型的情况下获取类型变量?,haskell,Haskell,作为初学者,我不清楚为什么不允许这样做: data Pair = Pair a b 也就是说,为什么对5“foo”和对“C”[必须生成不同的类型?为什么不允许它们都创建类型为Pair的值 我正在学习“learning you a”、RWH和Haskell WikiBook,但还没有找到一种精确的、不可靠的语言来描述我正在寻找的参数化类型。从根本上说,问题是你没有关于Pair内容的信息。如果您只知道它包含任何类型的值,那么您可以在它上使用的唯一真正的函数将是id,这是非常无用的 问题是,由于每个

作为初学者,我不清楚为什么不允许这样做:

data Pair = Pair a b
也就是说,为什么
对5“foo”
对“C”[
必须生成不同的类型?为什么不允许它们都创建类型为
Pair
的值


我正在学习“learning you a”、RWH和Haskell WikiBook,但还没有找到一种精确的、不可靠的语言来描述我正在寻找的参数化类型。

从根本上说,问题是你没有关于
Pair
内容的信息。如果您只知道它包含任何类型的值,那么您可以在它上使用的唯一真正的函数将是
id
,这是非常无用的

问题是,由于每个值都可以是任何值,因此您根本无法保证它们。所以你甚至不能使用
=
:如果这个值是一个函数呢?你不能比较函数是否相等

想象一下,编写一个作用于假设的
类型的函数:

fn (Pair a b) = ...
您可以在
a
b
上使用哪些其他功能

任何具体类型的东西(例如
Int->Int
或其他东西)都不起作用,因为你无法判断
a
是否是
Int
。像
numn=>n->n
这样更复杂的类型不起作用,因为您甚至不知道
a
是否是一个数字。唯一可以工作的函数是类型为
t1->t1
t1->t2
的函数。然而,第一种类型的唯一合理功能是
id
,而第二种类型的功能根本不合理


现在,你可以说“我要尝试这个函数,如果类型不起作用,抛出一个错误。”但这将是动态类型,基本上是完全抛弃类型系统。这听起来很可怕,但有时可能有道理,所以您可以使用
Data.Dynamic
来完成类似的操作。不过,作为初学者,您不必担心它,而且您可能永远都不需要使用它——到目前为止,我还没有使用过。为了完整起见,我将其包括在内。

通过存在类型语言扩展,您可以定义这样的类型:

{-# LANGUAGE ExistentialQuantification #-}

data Pair = forall a b. Pair a b

a, b :: Pair                                
a = Pair 1 2
b = Pair "abc" 'x'
此处
a
b
的类型相同

通常这不是这样做的,因为要对
做任何有用的事情,您需要知道它包含什么,而
的定义会删除所有这些信息


因此,如果您真的愿意,您可以创建这样的值,但很难找到任何有用的方法来处理它们。

那么,投影的类型是什么?Haskell有静态类型系统,您所要求的需要运行时类型检查。您可以使用扩展名(
data Pair=forall a b.Pair a b
)定义该类型,但它仍然没有用,正如Vitus和Tikhon.Vitus所解释的,通过投影,你是说一个返回一个组件值的函数吗?丹尼尔-谢谢。。。我将在大约一年后检查这些东西:)@spartan\u dev:确实如此。对于pair(大小为2的元组),它们是
fst
snd