haskell和类型多重声明错误

haskell和类型多重声明错误,haskell,types,algebraic-data-types,Haskell,Types,Algebraic Data Types,这使得a和B的和类型为AB 但最后一行导致编译错误“B的多个声明” 我也试过这样的东西: data A=A data B=B data AB=A|B 它编译。但是为什么ghc不允许我为用户定义的类型创建求和类型?因为使用数据构造函数A或B创建的值的类型将是不明确的。例如,当我有a=B时,a的类型是什么?它是A还是AB 您应该考虑使用不同的数据构造函数如下: data A=Int|Bool data A=A data B=B data AB=L A|R B 因为使用数据构造函数A或B创建的值

这使得a和B的和类型为AB

但最后一行导致编译错误“B的多个声明”

我也试过这样的东西:

data A=A
data B=B
data AB=A|B

它编译。但是为什么ghc不允许我为用户定义的类型创建求和类型?

因为使用数据构造函数
A
B
创建的值的类型将是不明确的。例如,当我有
a=B
时,
a
的类型是什么?它是
A
还是
AB

您应该考虑使用不同的数据构造函数如下:

data A=Int|Bool
data A=A
data B=B
data AB=L A|R B

因为使用数据构造函数
A
B
创建的值的类型将不明确。例如,当我有
a=B
时,
a
的类型是什么?它是
A
还是
AB

您应该考虑使用不同的数据构造函数如下:

data A=Int|Bool
data A=A
data B=B
data AB=L A|R B

当您说
data AB=A | B
时,您指的不是类型
A
B
,而是定义数据构造函数
A
B
。这些与前几行中定义的构造函数冲突

如果要创建一个类型
AB
,它是
a
B
的总和,则必须提供包装类型
a
B
的数据构造函数,例如:

data A = MkA
data B = MkB
data AB = A A | B B

当您说
data AB=A | B
时,您指的不是类型
A
B
,而是定义数据构造函数
A
B
。这些与前几行中定义的构造函数冲突

如果要创建一个类型
AB
,它是
a
B
的总和,则必须提供包装类型
a
B
的数据构造函数,例如:

data A = MkA
data B = MkB
data AB = A A | B B

你被愚弄了。你认为当你写
data A=Int | Bool
时,你是说
A
类型的值可以是
Int
类型的值,也可以是
Bool
类型的值;但实际上您要说的是,有两个新的值级构造函数名为
Int
Bool
,它们都不包含任何信息,类型为
A
。类似地,您认为
data AB=A | B
表示您可以是
A
类型或
B
类型,但实际上您是说您可以是value
A
或value
B

要记住的关键是有两个名称空间,类型级别和术语级别,并且它们是不同的

下面是一个简单的示例,说明如何正确操作:

data AB = ABA A | ABB B
最后一行声明了两个新的术语级构造函数,
L
R
L
构造函数携带类型为
a
的值,而
R
构造函数携带类型为
B
的值

您可能还喜欢
类型,定义如下:

data A=Int|Bool
data A=A
data B=B
data AB=L A|R B
如果您愿意,您可以使用它来实现
AB

data Either a b = Left a | Right b

类似地,您可以使用
Int Bool
作为
Int
Bool
的标记并集,这样您就被愚弄了。你认为当你写
data A=Int | Bool
时,你是说
A
类型的值可以是
Int
类型的值,也可以是
Bool
类型的值;但实际上您要说的是,有两个新的值级构造函数名为
Int
Bool
,它们都不包含任何信息,类型为
A
。类似地,您认为
data AB=A | B
表示您可以是
A
类型或
B
类型,但实际上您是说您可以是value
A
或value
B

要记住的关键是有两个名称空间,类型级别和术语级别,并且它们是不同的

下面是一个简单的示例,说明如何正确操作:

data AB = ABA A | ABB B
最后一行声明了两个新的术语级构造函数,
L
R
L
构造函数携带类型为
a
的值,而
R
构造函数携带类型为
B
的值

您可能还喜欢
类型,定义如下:

data A=Int|Bool
data A=A
data B=B
data AB=L A|R B
如果您愿意,您可以使用它来实现
AB

data Either a b = Left a | Right b

类似地,您可以使用
Int Bool
作为标记的
Int
Bool

总和类型的联合
a+a
必须从
a
进行两次注射

要了解代数数据类型如何工作,请举一个简单的示例:

type AB = Either A B
这定义了一个新的类型构造函数,
X
,以及数据构造函数
a
B
B
构造函数接受/持有类型为C的参数

Haskell中的主要规范和类型是

data X = A | B C

必须标记总和类型
a+a
必须从
a
进行两次注射

要了解代数数据类型如何工作,请举一个简单的示例:

type AB = Either A B
这定义了一个新的类型构造函数,
X
,以及数据构造函数
a
B
B
构造函数接受/持有类型为C的参数

Haskell中的主要规范和类型是

data X = A | B C

我猜你的意思是
数据AB=aa | bb
。毕竟,它应该是a和B的求和类型。啊,对了,谢谢你的更正,我想你是指
data AB=a a | B
。毕竟,它应该是a和B的总和类型。啊,对了,感谢你的更正,写这篇文章的意思是,既然
a
B
都不携带额外的信息,人们可能会完全扔掉它们,使用
数据AB=a | B
,但是如果没有额外的代码,这是很难看到的。@Zeta我假设
数据A=A
数据B=