繁体   English   中英

在Haskell中使用数据类型

[英]Using data types in Haskell

我已经开始这是一个新问题,因为它成为我上一个问题的后续问题。

如果我有两个由类似构造函数组成的数据类型:

data A = X | Y | Z
data B = X | Y

是不是我不能以某种方式表示这个:

data A = C | Z
data B = C

data C = X | Y

如果你能看到我在做什么 - 我正在尝试将X |分组 Y为一种数据类型,然后可由多种其他数据类型使用。 我似乎无法让编译器允许这个,或者如果它,我不能模式匹配X或Y,只有C ??

我收到多次声明C的错误消息。

我以为我可以使用类型,但它们不允许多种类型。

编辑

即使我声明了很长的路(如下所示),它仍然无法编译,并且说X和Y有多个声明:

data A = X | Y | Z
data B = X | Y

你不仅不能这样做,你也不能做你的第一个选择 - 即你不能在同一模块中有两种类型,它们都有名为XY构造函数。

如果你能做到这一点, X的类型应该是什么 - CAB 最明显的答案是C ,但是你不能在需要AB的上下文中使用它(注意Haskell没有子类型),这样就会破坏整个构造的目的。

你能做的最好的事情是将C包装在A和B的构造函数中,即:

data A = AC C | Z
data B = BC C
data C = X | Y

然后,您可以使用ACBC构造函数包装C,以分别创建类型AB的值。

你不能这样做的原因

data A = X | Y | Z
data B = X | Y

如下。 假设你稍后写了一些代码:

foo n = (n,X)

它构建了一对由第一个槽中的n和第二个槽中的X组成的对。 编译器应该推断出什么类型? 有效的类型是

foo :: a -> A -> (a,A)

因为XA类型的构造函数,但同样有效

foo :: a -> B -> (a,B)

因为XB类的构造函数。 如果有两个具有相同名称的构造函数,则无法推断使用它们的函数的唯一类型。 因此,您不允许在同一模块中为两个构造函数提供相同的名称。

你不能这样做:

data A = C | Z
data B = C

data C = X | Y

(顺便说一句,如果B C 相同 ,那么为什么要有B ?)

但你可以做的是这样的事情:

data A = A_Other C | Z
data B = B_Other C

data C = X | Y

然后你可以像这样模式匹配:

foo :: A -> String
foo (A_Other X) = "X"
foo (A_Other Y) = "Y"
foo (        Z) = "Z"

bar :: B -> String
bar (B_Other X) = "X"
bar (B_Other Y) = "Y"

foobar :: C -> String
foobar X = "X"
foobar Y = "Y"

如果这是有道理的......

你不能做你想要的,因为你声明了多个数据构造函数。

data A = X | Y | Z

实际上,您正在引入具有3个构造函数(值) XYZ的类型A 这就是为什么你的第一段代码不能编译,它会看到同样的名称被列为两种不同类型的构造函数! 如果你能做到这一点,你必须问自己是

X :: A

要么

X :: B

在非面向对象的环境中,这是可怕的! 因此,您需要提供不同的构造函数名称来共享底层数据C

如果你想要考虑这一点,你可以这样做,因为其他帖子在每个数据类型的唯一构造函数中都有建议和分解数据

data A = CForA C | Z
data B = CForB C

data C = X | Y

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM