[英]haskell sum type multiple declaration error
data A=A
data B=B
data AB=A|B
Which makes a sum type AB from A and B. 根据A和B得出总和类型AB。
but the last line induces a compile error "multiple declarations of B" 但最后一行引发了编译错误“ B的多个声明”
I also tried sth like this: 我也尝试过这样的事情:
data A=Int|Bool
It compiles. 它编译。 but why ghc disallows me from making sum types for user-defined types?
但是为什么ghc不允许我为用户定义类型创建求和类型?
You're getting fooled. 你被骗了。 You think when you write
data A=Int|Bool
that you are saying that a value of type A
can be a value of type Int
or a value of type Bool
; 您认为当您写
data A=Int|Bool
,您是在说A
类型的值可以是Int
类型的值或Bool
类型的值; but what you are actually saying is that there are two new value-level constructors named Int
and Bool
, each containing no information at all, of type A
. 但是您实际上要说的是,有两个名为
Int
和Bool
新值级别构造函数,每个都根本不包含任何信息,类型为A
Similarly, you think that data AB=A|B
says you can either be of type A
or type B
, but in fact you are saying you can either have value A
or value B
. 同样,您认为
data AB=A|B
表示您可以是A
类型或B
类型,但实际上您是在说您可以具有值 A
或值 B
The key thing to keep in mind is that there are two namespaces, type-level and term-level, and that they are distinct. 要记住的关键是,有两个名称空间,类型级别和术语级别,并且它们是不同的。
Here is a simple example of how to do it right: 这是一个正确的方法的简单示例:
data A=A
data B=B
data AB=L A|R B
The last line declares two new term-level constructors, L
and R
. 最后一行声明了两个新的术语级构造函数
L
和R
The L
constructor carries a value of type A
, while the R
constructor carries a value of type B
. L
构造函数带有类型 A
的值,而R
构造函数带有类型 B
的值。
You might also like the Either
type, defined as follows: 您可能还喜欢以下定义的
Either
类型:
data Either a b = Left a | Right b
You could use this to implement your AB
if you wanted: 如果需要,可以使用此方法来实现
AB
:
type AB = Either A B
Similarly, you could use Either Int Bool
for your tagged union of Int
and Bool
. 同样,您可以将
Either Int Bool
用于标记的Int
和Bool
联合。
Because the type of the value created using data constructor A
or B
will be ambiguous. 因为使用数据构造函数
A
或B
创建的值的类型将是模棱两可的。 When I have a = B
for instance, what is the type of a
? 例如,当我有
a = B
, a
的类型a
什么? It is A
or AB
? 是
A
还是AB
?
You should consider using different data constructor as follows: 您应该考虑使用以下不同的数据构造函数:
data A = MkA
data B = MkB
data AB = A A | B B
When you say data AB = A | B
当您说
data AB = A | B
data AB = A | B
, you are not referring to the types A
and B
, but rather are defining data constructors A
and B
. data AB = A | B
,您不是在引用类型 A
和B
,而是在定义数据构造函数 A
和B
These conflict with the constructors defined on the the previous lines. 这些与前几行中定义的构造函数冲突。
If you want to create a type AB
that is the sum of A
and B
, you must provide data constructors that wrap the types A
and B
, eg: 如果你想创建一个类型
AB
是的总和A
和B
,你必须提供的数据构造函数包裹类型A
和B
,如:
data AB = ABA A | ABB B
Sum types have to be tagged. 总和类型必须加标签。
a+a
has to have two injections from a
. a+a
必须从a
进行两次注入 。
To understand how algebraic data types work, take a simple example: 要了解代数数据类型如何工作,请举一个简单的示例:
data X = A | B C
This defines a new type constructor, X
, along with data constructors A
and B
. 这定义了一个新的类型构造函数
X
以及数据构造函数A
和B
The B
constructor takes/holds an argument of type C. B
构造函数采用/持有C类型的参数。
The primary canonical sum type in Haskell is Either
: Haskell中主要的规范和类型为
Either
:
data Either a b = Left a | Right b
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.