data A=A
data B=B
data AB=A|B
其中A和B的和型为AB。
但是最后一行引发了编译错误“B的多个声明”
我也尝试过这样:
data A=Int|Bool
它编译。但为什么ghc不允许我为用户定义的类型创建和类型?
答案 0 :(得分:5)
你被愚弄了。您认为在撰写data A=Int|Bool
时,您说A
类型的值可以是Int
类型的值或类型Bool
的值;但你实际所说的是,有两个名为Int
和Bool
的新值级构造函数,每个构造函数都不包含A
类型的信息。同样,您认为data AB=A|B
表示您可以是A
类型或B
类型,但实际上您说您可以拥有 value {{ 1}}或值 A
。
要记住的关键是有两个名称空间,类型级别和术语级别,它们是不同的。
以下是如何正确执行此操作的简单示例:
B
最后一行声明了两个新的术语级构造函数data A=A
data B=B
data AB=L A|R B
和L
。 R
构造函数的值为 type L
,而A
构造函数的值为 type R
您可能也喜欢B
类型,定义如下:
Either
如果您愿意,可以使用它来实现data Either a b = Left a | Right b
:
AB
同样,您可以将type AB = Either A B
用于Either Int Bool
和Int
的已标记联合。
答案 1 :(得分:1)
因为使用数据构造函数myButton
或jobList
创建的值的类型不明确。例如,如果我有A
,那么B
的类型是什么?它是a = B
还是a
?
您应该考虑使用不同的数据构造函数,如下所示:
A
答案 2 :(得分:1)
当您说data AB = A | B
时,您不是指类型 A
和B
,而是定义数据构造函数 A
和B
。这些与前面几行中定义的构造函数冲突。
如果要创建AB
和A
之和的类型B
,则必须提供包含类型A
和{{1}的数据构造函数例如:
B
答案 3 :(得分:1)
必须标记总和类型。 a+a
必须从a
进行两次注入。
要了解代数数据类型的工作原理,请举一个简单的例子:
data X = A | B C
这定义了一个新类型构造函数X
,以及数据构造函数A
和B
。 B
构造函数接受/保存类型为C的参数。
Haskell中的主要规范和类型是Either
:
data Either a b = Left a | Right b