创建数据类型时遇到了一些问题。
我有两种数据类型,足球和网球
data Football a = Football
{ players :: Players a
, Stadium :: Stadium a
}
data Tennis a = Tennis
{ players1 :: Players a
, Stadium1 :: Stadium a
}
我想创建另一个数据类型Sport使用数据类型football和tennis作为构造函数
data Sport a = Football a | Tennis a
我得到以下错误,足球的多个声明我不明白我做错了什么。
祝你好运
答案 0 :(得分:8)
你的想法在精神上是正确的,但Haskell使用标记的联合(也称为“歧视联盟”,“不相交的联盟”,“变体”和“和类型”)。这意味着你需要一个额外的标签来确定Sport是用Football构建的,还是用Tennis构建的。
data Sport = SportFootball Football | SportTennis Tennis
这些标记在Haskell中称为数据构造函数。也就是说,这定义了构造函数SportFootball :: Football -> Sport
和构造函数SportTennis :: Tennis -> Sport
。
假设Haskell不需要这个额外的标签,那么这种类型会是什么?
data UntaggedInt = Int | Int
未标记的联合应具有属性(x | x) = x
,因此必须等同于:
data UntaggedInt = Int
鉴于标记的联合,我们可以定义:
data TaggedInt = This Int | That Int
也就是说,标记的联合不是幂等。
还要考虑没有构造函数的其他事情。假设我们有一个定义,如:
data UntaggedLists = String | [String]
现在我们的任务是找到表达式"hello world"
的类型。类型应为String
还是UntaggedLists
?然后假设我们有另一个类似的定义:
data AnotherUntaggedLists = String | [String]
UntaggedLists
和AnotherUntaggedLists
是相同的类型吗?
这些不是无法回答的问题,但它确实表明在有标签之间存在深刻的系统差异。